Rewrote Com_strcpy() and Com_strcat() in game DLLs to not be based on strncpy() and to return size copied.

Changed Zaero and 3ZB2 game DLLs to use WORLD_SIZE for various calculations instead of 8192.
Cleaned up string handling in 3ZB2 game DLL.
Added func_plat2, func_door_secret2, and func_force_wall from Rogue to 3ZB2 game DLL.
Added alternate attack contact explode for grenade launcher in 3ZB2 game DLL.
Added awakening2 game DLL source.
This commit is contained in:
Knightmare66 2021-02-01 20:19:52 -05:00
parent 4afc95c317
commit 9481c7c513
80 changed files with 64904 additions and 2172 deletions

View file

@ -153,6 +153,10 @@ SOURCE=.\g_mtrain.c
# End Source File
# Begin Source File
SOURCE=.\g_newfnc.c
# End Source File
# Begin Source File
SOURCE=.\g_phys.c
# End Source File
# Begin Source File

View file

@ -112,101 +112,6 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/3zb2_2008.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;BUILDING_REF_GL"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/3zb2_2008.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="1"
DisableSpecificWarnings="4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile=".\gamex86.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\game.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/gamex86.pdb"
SubSystem="2"
BaseAddress="0x20000000"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary=".\Debug/gamex86.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/3zb2_2008.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
@ -302,6 +207,101 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/3zb2_2008.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;BUILDING_REF_GL"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/3zb2_2008.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="1"
DisableSpecificWarnings="4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile=".\gamex86.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\game.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/gamex86.pdb"
SubSystem="2"
BaseAddress="0x20000000"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary=".\Debug/gamex86.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/3zb2_2008.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
@ -417,7 +417,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -425,7 +425,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -453,7 +453,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -461,7 +461,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -489,7 +489,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -497,7 +497,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -525,7 +525,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -533,7 +533,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -561,7 +561,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -569,7 +569,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -597,7 +597,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -605,7 +605,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -633,7 +633,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -641,7 +641,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -669,7 +669,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -677,7 +677,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -705,7 +705,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -713,7 +713,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -741,7 +741,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -749,7 +749,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -777,7 +777,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -785,7 +785,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -813,7 +813,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -821,7 +821,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -853,7 +853,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -861,7 +861,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -881,6 +881,10 @@
RelativePath=".\g_mtrain.c"
>
</File>
<File
RelativePath=".\g_newfnc.c"
>
</File>
<File
RelativePath="g_phys.c"
>
@ -893,7 +897,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -901,7 +905,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -929,7 +933,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -937,7 +941,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -965,7 +969,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -973,7 +977,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1001,7 +1005,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1009,7 +1013,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1037,7 +1041,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1045,7 +1049,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1073,7 +1077,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1081,7 +1085,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1109,7 +1113,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1117,7 +1121,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1145,7 +1149,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1153,7 +1157,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1181,7 +1185,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1189,7 +1193,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1217,7 +1221,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1225,7 +1229,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1253,7 +1257,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1261,7 +1265,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1289,7 +1293,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1297,7 +1301,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1325,7 +1329,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1333,7 +1337,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1361,7 +1365,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1369,7 +1373,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1397,7 +1401,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1405,7 +1409,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1433,7 +1437,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1441,7 +1445,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"

View file

@ -10,18 +10,18 @@ qboolean Get_YenPos(char *Buff,int *curr)
while(1)
{
// if(i >= strlen(Buff)) return false;
if(Buff[i] == 0 || Buff[i] == 10 || Buff[i] == 13)
// if (i >= strlen(Buff)) return false;
if (Buff[i] == 0 || Buff[i] == 10 || Buff[i] == 13)
{
*curr = i;
return true;
}
if(Buff[i] == '\\')
if (Buff[i] == '\\')
{
*curr = i;
return true;
}
if(Buff[i] == '\t') Buff[i] = 0;
if (Buff[i] == '\t') Buff[i] = 0;
i++;
}
}
@ -45,10 +45,14 @@ void Load_BotInfo()
//init message
memset(ClientMessage,0,sizeof(ClientMessage));
//set message section
if(!ctf->value && chedit->value) strcpy(MessageSection,MESS_CHAIN_DM);
else if(ctf->value && !chedit->value) strcpy(MessageSection,MESS_CTF);
else if(ctf->value && chedit->value) strcpy(MessageSection,MESS_CHAIN_CTF);
else strcpy(MessageSection,MESS_DEATHMATCH);
if (!ctf->value && chedit->value)
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CHAIN_DM);
else if (ctf->value && !chedit->value)
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CTF);
else if (ctf->value && chedit->value)
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CHAIN_CTF);
else
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_DEATHMATCH);
//init botlist
ListedBots = 0;
@ -56,12 +60,12 @@ void Load_BotInfo()
for(i = 0;i < MAXBOTS;i++)
{
//netname
sprintf(Buff,"Zigock[%i]",i);
strcpy(Bot[i].netname,Buff);
Com_sprintf (Buff, sizeof(Buff), "Zigock[%i]",i);
Com_strcpy (Bot[i].netname, sizeof(Bot[i].netname), Buff);
//model
strcpy(Bot[i].model,"male");
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), "male");
//skin
strcpy(Bot[i].model,"grunt");
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), "grunt");
//param
Bot[i].param[BOP_WALK] = 0;
@ -77,7 +81,7 @@ void Load_BotInfo()
Bot[i].spflg = 0;
//team
Bot[i].team = j;
if(++j > 2) j = 1;
if (++j > 2) j = 1;
}
//botlist value
@ -85,9 +89,9 @@ void Load_BotInfo()
gamepath = gi.cvar ("game", "0", CVAR_NOSET);
//load info
sprintf(Buff,".\\%s\\3ZBconfig.cfg",gamepath->string);
fp = fopen(Buff,"rt");
if(fp == NULL)
Com_sprintf (Buff, sizeof(Buff), ".\\%s\\3ZBconfig.cfg",gamepath->string);
fp = fopen(Buff, "rt");
if (fp == NULL)
{
gi.dprintf("3ZB CFG: file not found.\n");
return;
@ -97,75 +101,79 @@ void Load_BotInfo()
fseek( fp, 0, SEEK_SET); //先頭へ移動
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
if (!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
}
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
if(Buff[0] == '.' || Buff[0] == '[' || Buff[0] == '#') break;
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
if (Buff[0] == '.' || Buff[0] == '[' || Buff[0] == '#') break;
k = (int)strlen(Buff);
if((strlen(Buff) + strlen(ClientMessage)) > MAX_STRING_CHARS - 1) break;
strcat(ClientMessage,Buff);
if ((strlen(Buff) + strlen(ClientMessage)) > MAX_STRING_CHARS - 1) break;
Com_strcat (ClientMessage, sizeof(ClientMessage), Buff);
}
MESS_NOTFOUND:
//if(botlist->string == NULL) strcpy(MessageSection,BOTLIST_SECTION_DM);
//else
sprintf(MessageSection,"[%s]",botlist->string);
// if (botlist->string == NULL)
// Com_strcpy (MessageSection, sizeof(MessageSection), BOTLIST_SECTION_DM);
// else
Com_sprintf (MessageSection, sizeof(MessageSection), "[%s]",botlist->string);
fseek( fp, 0, SEEK_SET); //先頭へ移動
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL)
if (fgets( Buff, sizeof(Buff), fp ) == NULL)
{
MessageSection[0] = 0;
break;
}
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
if (!Q_strncasecmp(MessageSection, Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
}
//when not found
if(MessageSection[0] == 0)
if (MessageSection[0] == 0)
{
strcpy(MessageSection,BOTLIST_SECTION_DM);
Com_strcpy (MessageSection, sizeof(MessageSection), BOTLIST_SECTION_DM);
fseek( fp, 0, SEEK_SET); //先頭へ移動
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto BOTLIST_NOTFOUND;
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto BOTLIST_NOTFOUND;
if (!Q_strncasecmp(MessageSection, Buff, strlen(MessageSection))) break; // Knightmare- was _strnicmp()
}
}
i = 0;
for(i = 0;i < MAXBOTS;i++)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) break;
if(Buff[0] == '[') break;
if(Buff[0] == '\n' || Buff[0] == '#') {i--;continue;}
if (fgets( Buff, sizeof(Buff), fp ) == NULL) break;
if (Buff[0] == '[') break;
if (Buff[0] == '\n' || Buff[0] == '#') {i--;continue;}
j = 2,k = 1;
if(!strncmp(Buff,"\\\\",2))
if (!strncmp(Buff,"\\\\",2))
{
//netname
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].netname,&Buff[j]);
if (strlen(&Buff[j]) < 21)
Com_strcpy (Bot[i].netname, sizeof(Bot[i].netname), &Buff[j]);
j = k + 1;
}
else break;
//model name
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].model,&Buff[j]);
if (strlen(&Buff[j]) < 21)
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), &Buff[j]);
j = k + 1;
k++;
}
else break;
//skin name
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].skin,&Buff[j]);
if (strlen(&Buff[j]) < 21)
Com_strcpy (Bot[i].skin, sizeof(Bot[i].skin), &Buff[j]);
j = k + 1;
k++;
}
@ -173,7 +181,7 @@ MESS_NOTFOUND:
for(l = 0;l < MAXBOP;l++)
{
//param0-7
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
Bot[i].param[l] = (unsigned char)atoi(&Buff[j]);
@ -182,25 +190,25 @@ MESS_NOTFOUND:
}
else break;
}
if(l < MAXBOP) break;
if (l < MAXBOP) break;
//team
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
if(Buff[j] == 'R') Bot[i].team = 1;
else if(Buff[j] == 'B') Bot[i].team = 2;
if (Buff[j] == 'R') Bot[i].team = 1;
else if (Buff[j] == 'B') Bot[i].team = 2;
else Bot[i].team = 1;
j = k + 1;
k++;
}
else break;
//auto spawn
if(Get_YenPos(Buff,&k))
if (Get_YenPos(Buff,&k))
{
Buff[k] = 0;
Bot[i].spflg = atoi(&Buff[j]);
//gi.dprintf("%i %s\n",Bot[i].spflg,&Buff[j]);
if(Bot[i].spflg == BOT_SPRESERVED && autospawn->value && !chedit->value) SpawnWaitingBots++;
if (Bot[i].spflg == BOT_SPRESERVED && autospawn->value && !chedit->value) SpawnWaitingBots++;
else Bot[i].spflg = BOT_SPAWNNOT;
}
else break;
@ -282,21 +290,21 @@ void Bot_Think (edict_t *self)
M_CheckGround (self);
}
if(self->deadflag)
if (self->deadflag)
{
if(self->client->ctf_grapple) CTFPlayerResetGrapple(self);
if (self->client->ctf_grapple) CTFPlayerResetGrapple(self);
if(self->s.modelindex == skullindex || self->s.modelindex == headindex) self->s.frame = 0;
else if(self->s.frame < FRAME_crdeath1 && self->s.frame != 0) self->s.frame = FRAME_death308;
if (self->s.modelindex == skullindex || self->s.modelindex == headindex) self->s.frame = 0;
else if (self->s.frame < FRAME_crdeath1 && self->s.frame != 0) self->s.frame = FRAME_death308;
self->s.modelindex2 = 0; // remove linked weapon model
//ZOID
self->s.modelindex3 = 0; // remove linked ctf flag
//ZOID
self->client->zc.route_trace = false;
if(self->client->respawn_time <= level.time)
if (self->client->respawn_time <= level.time)
{
if(self->svflags & SVF_MONSTER)
if (self->svflags & SVF_MONSTER)
{
self->client->respawn_time = level.time;
CopyToBodyQue (self);
@ -307,7 +315,7 @@ void Bot_Think (edict_t *self)
else
{
Bots_Move_NORM (self);
if(!self->inuse) return; //removed botself
if (!self->inuse) return; //removed botself
client = self->client;
@ -353,7 +361,7 @@ void InitializeBot (edict_t *ent,int botindex )
client->resp.enterframe = level.framenum;
//set netname model skil and CTF team
sprintf(pinfo,"\\rate\\25000\\msg\\1\\fov\\90\\skin\\%s/%s\\name\\%s\\hand\\0",Bot[botindex].model,Bot[botindex].skin,Bot[botindex].netname);
Com_sprintf (pinfo, sizeof(pinfo), "\\rate\\25000\\msg\\1\\fov\\90\\skin\\%s/%s\\name\\%s\\hand\\0",Bot[botindex].model,Bot[botindex].skin,Bot[botindex].netname);
ent->client->resp.ctf_team = Bot[botindex].team; //CTF_TEAM1,CTF_TEAM2
ClientUserinfoChanged (ent, pinfo);
@ -376,7 +384,7 @@ void InitializeBot (edict_t *ent,int botindex )
gi.dprintf ("%s connected\n", ent->client->pers.netname);
// gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname);
if(ctf->value) gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
if (ctf->value) gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
client->pers.netname, CTFTeamName(ent->client->resp.ctf_team));
else gi.bprintf (PRINT_HIGH, "%s entered the game\n",
client->pers.netname);
@ -429,7 +437,7 @@ void PutBotInServer (edict_t *ent)
client->ctf_grapple = NULL;
item = FindItem("Grapple");
if(ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
if (ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
//ZOID
// clear entity values
@ -480,7 +488,7 @@ void PutBotInServer (edict_t *ent)
VectorCopy (spawn_angles, ent->s.angles);
spawn_origin[2] -= 300;
rs_trace = gi.trace(ent->s.origin,ent->mins,ent->maxs,spawn_origin,ent,MASK_SOLID);
if(!rs_trace.allsolid) VectorCopy (rs_trace.endpos, ent->s.origin);
if (!rs_trace.allsolid) VectorCopy (rs_trace.endpos, ent->s.origin);
VectorSet(ent->velocity,0,0,0);
ent->moveinfo.speed = 0;
ent->groundentity = rs_trace.ent;
@ -512,14 +520,14 @@ void PutBotInServer (edict_t *ent)
zc->first_target = NULL;
zc->zcstate = STS_IDLE;
if(ent->client->resp.enterframe == level.framenum && !chedit->value)
if (ent->client->resp.enterframe == level.framenum && !chedit->value)
{
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_LOGIN);
gi.multicast (ent->s.origin, MULTICAST_PVS);
}
else if(!chedit->value)
else if (!chedit->value)
{
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
@ -532,12 +540,12 @@ void PutBotInServer (edict_t *ent)
entcount = gi.BoxEdicts ( ent->absmin ,ent->absmax,touch,MAX_EDICTS,AREA_SOLID);
while (entcount-- > 0)
{
if(Q_stricmp (touch[entcount]->classname, "player") == 0)
if(touch[entcount] != ent)
if (Q_stricmp (touch[entcount]->classname, "player") == 0)
if (touch[entcount] != ent)
T_Damage (touch[entcount], ent, ent, vec3_origin, touch[entcount]->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
}
if(ctf->value)
if (ctf->value)
{
CTFPlayerResetGrapple(ent);
client->zc.ctfstate = CTFS_OFFENCER;
@ -566,28 +574,28 @@ qboolean SpawnBot(int i)
//gi.cprintf (NULL,PRINT_HIGH,"Called %s %s %s\n",Bot[i].netname,Bot[i].model,Bot[i].skin);
//return false;
if( Get_NumOfPlayer () >= game.maxclients )
if ( Get_NumOfPlayer () >= game.maxclients )
{
gi.cprintf (NULL,PRINT_HIGH,"Can't add bots\n");
return false;
}
bot = Get_NewClient();
if(bot == NULL) return false;
if (bot == NULL) return false;
InitializeBot( bot , i);
PutBotInServer ( bot );
j = targetindex;
if(chedit->value)
if (chedit->value)
{
for(k = CurrentIndex - 1;k > 0 ;k--)
{
if(Route[k].index == 0) break;
if (Route[k].index == 0) break;
if(Route[k].state == GRS_NORMAL)
if (Route[k].state == GRS_NORMAL)
{
if(--j <= 0) break;
if (--j <= 0) break;
}
}
@ -607,7 +615,7 @@ qboolean SpawnBot(int i)
gi.multicast (bot->s.origin, MULTICAST_PVS);
ent = &g_edicts[1];
if(ent->inuse && ent->client && !(ent->svflags & SVF_MONSTER))
if (ent->inuse && ent->client && !(ent->svflags & SVF_MONSTER))
{
ent->takedamage = DAMAGE_NO;
ent->movetype = MOVETYPE_NOCLIP;
@ -636,9 +644,9 @@ void Bot_SpawnCall()
for(i = 0;i < MAXBOTS;i++)
{
if(Bot[i].spflg == BOT_SPRESERVED)
if (Bot[i].spflg == BOT_SPRESERVED)
{
if(SpawnBot(i)) Bot[i].spflg = BOT_SPAWNED;
if (SpawnBot(i)) Bot[i].spflg = BOT_SPAWNED;
else
{
Bot[i].spflg = BOT_SPAWNNOT;
@ -661,7 +669,7 @@ void SpawnBotReserving()
for(i = 0;i < MAXBOTS; i++)
{
if(Bot[i].spflg == BOT_SPAWNNOT)
if (Bot[i].spflg == BOT_SPAWNNOT)
{
Bot[i].spflg = BOT_SPRESERVED;
SpawnWaitingBots++;
@ -684,16 +692,16 @@ void SpawnBotReserving2(int *red,int *blue)
for(i = 0;i < ListedBots; i++,j++)
{
if(j >= ListedBots) j = 0;
if(Bot[j].spflg == BOT_SPAWNNOT)
if (j >= ListedBots) j = 0;
if (Bot[j].spflg == BOT_SPAWNNOT)
{
Bot[j].spflg = BOT_SPRESERVED;
SpawnWaitingBots++;
if(*red > *blue) Bot[j].team = 2;
if (*red > *blue) Bot[j].team = 2;
else Bot[j].team = 1;
if(Bot[j].team == 1) *red = *red + 1;
else if(Bot[j].team == 2) *blue = *blue + 1;
if (Bot[j].team == 1) *red = *red + 1;
else if (Bot[j].team == 2) *blue = *blue + 1;
//gi.cprintf(NULL,PRINT_HIGH,"team %i\n",Bot[j].team);
return;
}
@ -718,13 +726,13 @@ void RemoveBot()
for(i = MAXBOTS - 1;i >= 0;i--)
{
if(Bot[i].spflg == BOT_SPAWNED || Bot[i].spflg == BOT_NEXTLEVEL)
if (Bot[i].spflg == BOT_SPAWNED || Bot[i].spflg == BOT_NEXTLEVEL)
{
break;
}
}
if(i < 0)
if (i < 0)
{
gi.cprintf (NULL, PRINT_HIGH, "No Bots in server.");
return;
@ -735,16 +743,16 @@ void RemoveBot()
e = &g_edicts[(int)maxclients->value];
for ( i = maxclients->value ; i >= 1 ; i--, e--)
{
if(!e->inuse) continue;
if (!e->inuse) continue;
client = /*e->client;*/&game.clients[i - 1];
if(client == NULL) continue;
if (client == NULL) continue;
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (!client->pers.connected && (e->svflags & SVF_MONSTER))
{
if(client->zc.botindex == botindex)
if (client->zc.botindex == botindex)
{
if(Bot[botindex].spflg != BOT_NEXTLEVEL) Bot[botindex].spflg = BOT_SPAWNNOT;
if (Bot[botindex].spflg != BOT_NEXTLEVEL) Bot[botindex].spflg = BOT_SPAWNNOT;
else Bot[botindex].spflg = BOT_SPRESERVED;
gi.bprintf (PRINT_HIGH, "%s disconnected\n", e->client->pers.netname);
@ -771,11 +779,11 @@ void RemoveBot()
e->inuse = false;
G_FreeEdict (e);
if(targetindex)
if (targetindex)
{
ent = &g_edicts[1];
if(ent->inuse)
if (ent->inuse)
{
ent->health = 100;
ent->movetype = MOVETYPE_WALK;
@ -810,9 +818,9 @@ void Bot_LevelChange()
for(i = 0;i < MAXBOTS;i++)
{
if(Bot[i].spflg)
if (Bot[i].spflg)
{
if(Bot[i].spflg == BOT_SPAWNED)
if (Bot[i].spflg == BOT_SPAWNED)
{
k++;
Bot[i].spflg = BOT_NEXTLEVEL;
@ -845,7 +853,7 @@ void ZigockClientJoin(edict_t *ent,int zclass)
ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
ent->client->ps.pmove.pm_time = 14;
if(ctf->value)
if (ctf->value)
{
gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
ent->client->pers.netname, CTFTeamName(ent->client->resp.ctf_team/*desired_team*/));
@ -944,7 +952,7 @@ void AirSight_Think(edict_t *ent)
ent->s.modelindex = gi.modelindex ("sprites/airsight.sp2");
VectorCopy(ent->target_ent->s.origin,ent->s.origin);
if( ent->owner->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
if ( ent->owner->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
{
ent->s.frame = 1;
}
@ -973,16 +981,16 @@ void AirStrike_Think(edict_t *ent)
for ( i = 1 ; i <= maxclients->value; i++)
{
target = &g_edicts[i];
if(!target->inuse || target->deadflag || target == ent->owner) continue;
if (!target->inuse || target->deadflag || target == ent->owner) continue;
if( target->classname[0] == 'p')
if ( target->classname[0] == 'p')
{
//ctf ならチームメイト無視
if(!ctf->value || (ctf->value && ent->owner->client->resp.ctf_team != target->client->resp.ctf_team))
if (!ctf->value || (ctf->value && ent->owner->client->resp.ctf_team != target->client->resp.ctf_team))
{
rs_trace = gi.trace (point,NULL,NULL,target->s.origin,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME);
if(rs_trace.fraction == 1.0)
if (rs_trace.fraction == 1.0)
{
sight = G_Spawn();
@ -1015,12 +1023,12 @@ void Cmd_AirStrike(edict_t *ent)
rs_trace = gi.trace (ent->s.origin,NULL,NULL,strpoint,ent, MASK_SHOT);
if(!(rs_trace.surface && (rs_trace.surface->flags & SURF_SKY)))
if (!(rs_trace.surface && (rs_trace.surface->flags & SURF_SKY)))
{
gi.cprintf(ent,PRINT_HIGH,"can't call Viper.\n");
return;
}
/* if((rs_trace.endpos[2] - ent->s.origin[2]) < 300)
/* if ((rs_trace.endpos[2] - ent->s.origin[2]) < 300)
{
gi.cprintf(ent,PRINT_HIGH,"can't call Viper.\n");
}*/

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,7 @@ char *ClientTeam (edict_t *ent)
if (!ent->client)
return value;
strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
Com_strcpy (value, sizeof(value), Info_ValueForKey (ent->client->pers.userinfo, "skin"));
p = strchr(value, '/');
if (!p)
return value;
@ -35,8 +35,8 @@ qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
return false;
strcpy (ent1Team, ClientTeam (ent1));
strcpy (ent2Team, ClientTeam (ent2));
Com_strcpy (ent1Team, sizeof(ent1Team), ClientTeam (ent1));
Com_strcpy (ent2Team, sizeof(ent2Team), ClientTeam (ent2));
if (strcmp(ent1Team, ent2Team) == 0)
return true;
@ -829,10 +829,10 @@ void Cmd_Players_f (edict_t *ent)
game.clients[index[i]].pers.netname);
if (strlen (small) + strlen(large) > sizeof(large) - 100 )
{ // can't print all of them in one packet
strcat (large, "...\n");
Com_strcat (large, sizeof(large), "...\n");
break;
}
strcat (large, small);
Com_strcat (large, sizeof(large), small);
}
gi.cprintf (ent, PRINT_HIGH, "%s\n%i players\n", large, count);
@ -914,9 +914,9 @@ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
if (arg0)
{
strcat (text, gi.argv(0));
strcat (text, " ");
strcat (text, gi.args());
Com_strcat (text, sizeof(text), gi.argv(0));
Com_strcat (text, sizeof(text), " ");
Com_strcat (text, sizeof(text), gi.args());
}
else
{
@ -927,14 +927,14 @@ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
p++;
p[strlen(p)-1] = 0;
}
strcat(text, p);
Com_strcat (text, sizeof(text), p);
}
// don't let text be too long for malicious reasons
if (strlen(text) > 150)
text[150] = 0;
strcat(text, "\n");
Com_strcat (text, sizeof(text), "\n");
if (dedicated->value)
gi.cprintf(NULL, PRINT_CHAT, "%s", text);

File diff suppressed because it is too large Load diff

View file

@ -100,13 +100,13 @@ void train_spline (edict_t *self)
VectorScale(train->velocity, 10 ,train->velocity);
VectorSubtract(a, train->s.angles, train->avelocity);
VectorScale(train->avelocity, 10, train->avelocity);
if(train->pitch_speed < 0)
if (train->pitch_speed < 0)
train->avelocity[PITCH] = 0;
if (train->yaw_speed < 0)
train->avelocity[YAW] = 0;
gi.linkentity(train);
train->moveinfo.ratio += train->moveinfo.speed * FRAMETIME / train->moveinfo.distance;
// if(train->movewith_next && (train->movewith_next->movewith_ent == train))
// if (train->movewith_next && (train->movewith_next->movewith_ent == train))
// set_child_movement(train);
if (train->moveinfo.ratio >= 1.0)
{
@ -155,6 +155,14 @@ void train_spline (edict_t *self)
#define PLAT_LOW_TRIGGER 1
//====
//PGM
#define PLAT2_TOGGLE 2
#define PLAT2_TOP 4
#define PLAT2_TRIGGER_TOP 8
#define PLAT2_TRIGGER_BOTTOM 16
#define PLAT2_BOX_LIFT 32
#define STATE_TOP 0
#define STATE_BOTTOM 1
#define STATE_UP 2
@ -466,6 +474,9 @@ void plat_hit_top (edict_t *ent)
// ent->s.sound = 0;
}
ent->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
#ifdef LOOP_SOUND_ATTENUATION // Knightmare added
ent->s.attenuation = ent->attenuation;
#endif
ent->moveinfo.state = STATE_TOP;
@ -482,6 +493,9 @@ void plat_hit_bottom (edict_t *ent)
// ent->s.sound = 0;
}
ent->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
#ifdef LOOP_SOUND_ATTENUATION // Knightmare added
ent->s.attenuation = ent->attenuation;
#endif
ent->moveinfo.state = STATE_BOTTOM;
}
@ -528,7 +542,7 @@ void plat_blocked (edict_t *self, edict_t *other)
return;
}
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
if (self->moveinfo.state == STATE_UP)
@ -561,7 +575,9 @@ void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_
ent->nextthink = level.time + 1; // the player is still on the plat, so delay going down
}
void plat_spawn_inside_trigger (edict_t *ent)
// PGM - plat2's change the trigger field
//void plat_spawn_inside_trigger (edict_t *ent)
edict_t *plat_spawn_inside_trigger (edict_t *ent)
{
edict_t *trigger;
vec3_t tmin, tmax;
@ -608,6 +624,8 @@ void plat_spawn_inside_trigger (edict_t *ent)
VectorCopy (tmax, trigger->maxs);
gi.linkentity (trigger);
return trigger; // PGM 11/17/97
}
@ -720,6 +738,432 @@ void SP_func_plat (edict_t *ent)
SpawnItem3 (it_ent, it);
}
// ==========================================
// PLAT 2
// ==========================================
#define PLAT2_CALLED 1
#define PLAT2_MOVING 2
#define PLAT2_WAITING 4
void plat2_go_down (edict_t *ent);
void plat2_go_up (edict_t *ent);
void plat2_spawn_danger_area (edict_t *ent)
{
vec3_t mins, maxs;
VectorCopy(ent->mins, mins);
VectorCopy(ent->maxs, maxs);
maxs[2] = ent->mins[2] + 64;
// SpawnBadArea(mins, maxs, 0, ent);
}
void plat2_kill_danger_area (edict_t *ent)
{
edict_t *t;
t = NULL;
while ((t = G_Find (t, FOFS(classname), "bad_area")))
{
if (t->owner == ent)
G_FreeEdict(t);
}
}
void plat2_hit_top (edict_t *ent)
{
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_end)
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ent->attenuation, 0);
ent->s.sound = 0;
}
ent->moveinfo.state = STATE_TOP;
if (ent->plat2flags & PLAT2_CALLED)
{
ent->plat2flags = PLAT2_WAITING;
if (!(ent->spawnflags & PLAT2_TOGGLE))
{
ent->think = plat2_go_down;
ent->nextthink = level.time + 5.0;
}
if (deathmatch->value)
ent->last_move_time = level.time - 1.0;
else
ent->last_move_time = level.time - 2.0;
}
else if (!(ent->spawnflags & PLAT2_TOP) && !(ent->spawnflags & PLAT2_TOGGLE))
{
ent->plat2flags = 0;
ent->think = plat2_go_down;
ent->nextthink = level.time + 2.0;
ent->last_move_time = level.time;
}
else
{
ent->plat2flags = 0;
ent->last_move_time = level.time;
}
G_UseTargets (ent, ent);
}
void plat2_hit_bottom (edict_t *ent)
{
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_end)
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ent->attenuation, 0);
ent->s.sound = 0;
}
ent->moveinfo.state = STATE_BOTTOM;
if (ent->plat2flags & PLAT2_CALLED)
{
ent->plat2flags = PLAT2_WAITING;
if (!(ent->spawnflags & PLAT2_TOGGLE))
{
ent->think = plat2_go_up;
ent->nextthink = level.time + 5.0;
}
if (deathmatch->value)
ent->last_move_time = level.time - 1.0;
else
ent->last_move_time = level.time - 2.0;
}
else if ((ent->spawnflags & PLAT2_TOP) && !(ent->spawnflags & PLAT2_TOGGLE))
{
ent->plat2flags = 0;
ent->think = plat2_go_up;
ent->nextthink = level.time + 2.0;
ent->last_move_time = level.time;
}
else
{
ent->plat2flags = 0;
ent->last_move_time = level.time;
}
plat2_kill_danger_area (ent);
G_UseTargets (ent, ent);
}
void plat2_go_down (edict_t *ent)
{
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_start)
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ent->attenuation, 0);
ent->s.sound = ent->moveinfo.sound_middle;
}
ent->moveinfo.state = STATE_DOWN;
ent->plat2flags |= PLAT2_MOVING;
Move_Calc (ent, ent->moveinfo.end_origin, plat2_hit_bottom);
}
void plat2_go_up (edict_t *ent)
{
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_start)
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ent->attenuation, 0);
ent->s.sound = ent->moveinfo.sound_middle;
}
ent->moveinfo.state = STATE_UP;
ent->plat2flags |= PLAT2_MOVING;
plat2_spawn_danger_area(ent);
Move_Calc (ent, ent->moveinfo.start_origin, plat2_hit_top);
}
void plat2_operate (edict_t *ent, edict_t *other)
{
int otherState;
float pauseTime;
float platCenter;
edict_t *trigger;
trigger = ent;
ent = ent->enemy; // now point at the plat, not the trigger
if (ent->plat2flags & PLAT2_MOVING)
return;
if ((ent->last_move_time + 2) > level.time)
return;
platCenter = (trigger->absmin[2] + trigger->absmax[2]) / 2;
if (ent->moveinfo.state == STATE_TOP)
{
otherState = STATE_TOP;
if (ent->spawnflags & PLAT2_BOX_LIFT)
{
if (platCenter > other->s.origin[2])
otherState = STATE_BOTTOM;
}
else
{
if (trigger->absmax[2] > other->s.origin[2])
otherState = STATE_BOTTOM;
}
}
else
{
otherState = STATE_BOTTOM;
if (other->s.origin[2] > platCenter)
otherState = STATE_TOP;
}
ent->plat2flags = PLAT2_MOVING;
if (deathmatch->value)
pauseTime = 0.3;
else
pauseTime = 0.5;
if (ent->moveinfo.state != otherState)
{
ent->plat2flags |= PLAT2_CALLED;
pauseTime = 0.1;
}
ent->last_move_time = level.time;
if (ent->moveinfo.state == STATE_BOTTOM)
{
ent->think = plat2_go_up;
ent->nextthink = level.time + pauseTime;
}
else
{
ent->think = plat2_go_down;
ent->nextthink = level.time + pauseTime;
}
}
void Touch_Plat_Center2 (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
// this requires monsters to actively trigger plats, not just step on them.
//FIXME - commented out for E3
//if (!other->client)
// return;
if (other->health <= 0)
return;
// PMM - don't let non-monsters activate plat2s
if ((!(other->svflags & SVF_MONSTER)) && (!other->client))
return;
plat2_operate (ent, other);
}
void plat2_blocked (edict_t *self, edict_t *other)
{
if (!(other->svflags & SVF_MONSTER) && (!other->client))
{
// give it a chance to go away on it's own terms (like gibs)
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
// if it's still there, nuke it
if (other && other->inuse)
BecomeExplosion1 (other);
return;
}
// gib dead things
if (other->health < 1)
{
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100, 1, 0, MOD_CRUSH);
}
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
if (self->moveinfo.state == STATE_UP)
plat2_go_down (self);
else if (self->moveinfo.state == STATE_DOWN)
plat2_go_up (self);
}
void Use_Plat2 (edict_t *ent, edict_t *other, edict_t *activator)
{
edict_t *trigger;
int i;
if (ent->moveinfo.state > STATE_BOTTOM)
return;
if ((ent->last_move_time + 2) > level.time)
return;
for (i = 1, trigger = g_edicts + 1; i < globals.num_edicts; i++, trigger++)
{
if (!trigger->inuse)
continue;
if (trigger->touch == Touch_Plat_Center2)
{
if (trigger->enemy == ent)
{
// Touch_Plat_Center2 (trigger, activator, NULL, NULL);
plat2_operate (trigger, activator);
return;
}
}
}
}
void plat2_activate (edict_t *ent, edict_t *other, edict_t *activator)
{
edict_t *trigger;
// if (ent->targetname)
// ent->targetname[0] = 0;
ent->use = Use_Plat2;
trigger = plat_spawn_inside_trigger (ent); // the "start moving" trigger
trigger->maxs[0]+=10;
trigger->maxs[1]+=10;
trigger->mins[0]-=10;
trigger->mins[1]-=10;
gi.linkentity (trigger);
trigger->touch = Touch_Plat_Center2; // Override trigger touch function
plat2_go_down(ent);
}
/*QUAKED func_plat2 (0 .5 .8) ? PLAT_LOW_TRIGGER PLAT2_TOGGLE PLAT2_TOP PLAT2_TRIGGER_TOP PLAT2_TRIGGER_BOTTOM BOX_LIFT
speed default 150
PLAT_LOW_TRIGGER - creates a short trigger field at the bottom
PLAT2_TOGGLE - plat will not return to default position.
PLAT2_TOP - plat's default position will the the top.
PLAT2_TRIGGER_TOP - plat will trigger it's targets each time it hits top
PLAT2_TRIGGER_BOTTOM - plat will trigger it's targets each time it hits bottom
BOX_LIFT - this indicates that the lift is a box, rather than just a platform
Plats are always drawn in the extended position, so they will light correctly.
If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
"speed" overrides default 200.
"accel" overrides default 500
"lip" no default
If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determoveinfoned by the model's height.
*/
void SP_func_plat2 (edict_t *ent)
{
edict_t *trigger;
VectorClear (ent->s.angles);
ent->solid = SOLID_BSP;
ent->movetype = MOVETYPE_PUSH;
gi.setmodel (ent, ent->model);
ent->blocked = plat2_blocked;
if (!ent->speed)
ent->speed = 20;
else
ent->speed *= 0.1;
if (!ent->accel)
ent->accel = 5;
else
ent->accel *= 0.1;
if (!ent->decel)
ent->decel = 5;
else
ent->decel *= 0.1;
if (deathmatch->value)
{
ent->speed *= 2;
ent->accel *= 2;
ent->decel *= 2;
}
//PMM Added to kill things it's being blocked by
if (!ent->dmg)
ent->dmg = 2;
// if (!st.lip)
// st.lip = 8;
// pos1 is the top position, pos2 is the bottom
VectorCopy (ent->s.origin, ent->pos1);
VectorCopy (ent->s.origin, ent->pos2);
if (st.height)
ent->pos2[2] -= (st.height - st.lip);
else
ent->pos2[2] -= (ent->maxs[2] - ent->mins[2]) - st.lip;
ent->moveinfo.state = STATE_TOP;
if (ent->targetname)
{
ent->use = plat2_activate;
}
else
{
ent->use = Use_Plat2;
trigger = plat_spawn_inside_trigger (ent); // the "start moving" trigger
// PGM - debugging??
trigger->maxs[0]+=10;
trigger->maxs[1]+=10;
trigger->mins[0]-=10;
trigger->mins[1]-=10;
gi.linkentity (trigger);
trigger->touch = Touch_Plat_Center2; // Override trigger touch function
if (!(ent->spawnflags & PLAT2_TOP))
{
VectorCopy (ent->pos2, ent->s.origin);
ent->moveinfo.state = STATE_BOTTOM;
}
}
gi.linkentity (ent);
ent->moveinfo.speed = ent->speed;
ent->moveinfo.accel = ent->accel;
ent->moveinfo.decel = ent->decel;
ent->moveinfo.wait = ent->wait;
VectorCopy (ent->pos1, ent->moveinfo.start_origin);
VectorCopy (ent->s.angles, ent->moveinfo.start_angles);
VectorCopy (ent->pos2, ent->moveinfo.end_origin);
VectorCopy (ent->s.angles, ent->moveinfo.end_angles);
ent->moveinfo.sound_start = gi.soundindex ("plats/pt1_strt.wav");
ent->moveinfo.sound_middle = gi.soundindex ("plats/pt1_mid.wav");
ent->moveinfo.sound_end = gi.soundindex ("plats/pt1_end.wav");
if (ent->attenuation <= 0) // Knightmare added
ent->attenuation = ATTN_STATIC;
//Maj++
// bFuncPlat(ent);
//Maj--
}
//====================================================================
/*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS TOUCH_PAIN STOP ANIMATED ANIMATED_FAST
@ -742,7 +1186,7 @@ void rotating_blocked (edict_t *self, edict_t *other)
void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
//ponko
if(other->svflags & SVF_MONSTER) return;
if (other->svflags & SVF_MONSTER) return;
if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2])
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
@ -880,14 +1324,14 @@ void button_fire (edict_t *self)
return;
if(self->activator)
if (self->activator)
{
if(chedit->value && CurrentIndex < MAXNODES && !self->activator->deadflag && self->activator == &g_edicts[1])
if (chedit->value && CurrentIndex < MAXNODES && !self->activator->deadflag && self->activator == &g_edicts[1])
{
VectorCopy(self->monsterinfo.last_sighting,Route[CurrentIndex].Pt);
Route[CurrentIndex].ent = self;
Route[CurrentIndex].state = GRS_PUSHBUTTON;
if(++CurrentIndex < MAXNODES)
if (++CurrentIndex < MAXNODES)
{
gi.bprintf(PRINT_HIGH,"Last %i pod(s).\n",MAXNODES - CurrentIndex);
memset(&Route[CurrentIndex],0,sizeof(route_t));
@ -924,7 +1368,7 @@ void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *s
void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
// if(self->takedamage) self->monsterinfo.attack_finished = level.time + FRAMETIME * 40;
// if (self->takedamage) self->monsterinfo.attack_finished = level.time + FRAMETIME * 40;
self->activator = attacker;
self->health = self->max_health;
@ -998,7 +1442,7 @@ void SP_func_button (edict_t *ent)
VectorAdd(ent->s.origin,ent->mins,ent->monsterinfo.last_sighting);
// VectorCopy(ent->s.origin,ent->monsterinfo.last_sighting);
if(1/*!ent->health*/)
if (1/*!ent->health*/)
{
//sp roam navi
it = FindItem("Roam Navi2");
@ -1020,7 +1464,7 @@ void SP_func_button (edict_t *ent)
VectorScale (abs_movedir, dist, tdir);
VectorAdd(it_ent->s.origin,tdir,tdir2);
i = gi.pointcontents(tdir2);
if(!(i & CONTENTS_SOLID) ) break;
if (!(i & CONTENTS_SOLID) ) break;
dist++;
}
VectorScale (abs_movedir, (dist + 20), tdir);
@ -1107,7 +1551,7 @@ void door_hit_top (edict_t *self)
self->moveinfo.state = STATE_TOP;
if (self->spawnflags & DOOR_TOGGLE)
{
if(self->union_ent)
if (self->union_ent)
{
self->union_ent->solid = SOLID_NOT;
}
@ -1130,7 +1574,7 @@ void door_hit_bottom (edict_t *self)
}
self->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
if(self->union_ent)
if (self->union_ent)
{
self->union_ent->solid = SOLID_NOT;
}
@ -1335,7 +1779,7 @@ void door_blocked (edict_t *self, edict_t *other)
BecomeExplosion1 (other);
return;
}
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
//bot's state change
@ -1343,9 +1787,9 @@ void door_blocked (edict_t *self, edict_t *other)
{
ent = &g_edicts[i];
if(ent->inuse && (ent->svflags & SVF_MONSTER) && ent->client)
if (ent->inuse && (ent->svflags & SVF_MONSTER) && ent->client)
{
if(ent->client->zc.waitin_obj == self && ent->client->zc.zcstate )
if (ent->client->zc.waitin_obj == self && ent->client->zc.zcstate )
{
ent->client->zc.zcstate |= STS_W_DONT;
}
@ -1397,7 +1841,7 @@ void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *sur
return;
self->touch_debounce_time = level.time + 5.0;
if(!(other->svflags & SVF_MONSTER))
if (!(other->svflags & SVF_MONSTER))
{
gi.centerprintf (other, "%s", self->message);
gi.sound (other, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
@ -1506,7 +1950,7 @@ void SP_func_door (edict_t *ent)
// VectorCopy(ent->s.origin,ent->monsterinfo.last_sighting);
/////////
if(fabs(ent->moveinfo.start_origin[2] - ent->moveinfo.end_origin[2]) >20)
if (fabs(ent->moveinfo.start_origin[2] - ent->moveinfo.end_origin[2]) >20)
{
it = FindItem("Roam Navi3");
it_ent = G_Spawn();
@ -1753,12 +2197,13 @@ dmg default 2
noise looping sound to play when the train is in motion
*/
// Lazarus: Added health key to func_train
void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
// edict_t *e, *next;
if(self->deathtarget)
if (self->deathtarget)
{
self->target = self->deathtarget;
G_UseTargets (self, attacker);
@ -1768,11 +2213,11 @@ void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
while(e) {
next = e->movewith_next;
e->nextthink = 0;
if(e->takedamage)
if (e->takedamage)
T_Damage (e, self, self, vec3_origin, e->s.origin, vec3_origin, 100000, 1, DAMAGE_NO_PROTECTION, MOD_CRUSH);
else if(e->die)
else if (e->die)
e->die(e,self,self,100000,e->s.origin);
else if(e->solid == SOLID_NOT)
else if (e->solid == SOLID_NOT)
G_FreeEdict(e);
else
BecomeExplosion1 (e);
@ -1860,7 +2305,7 @@ void train_wait (edict_t *self)
{
VectorClear(self->avelocity);
VectorClear(self->velocity);
// if(self->movewith_next && (self->movewith_next->movewith_ent == self))
// if (self->movewith_next && (self->movewith_next->movewith_ent == self))
// set_child_movement(self);
}
@ -1879,7 +2324,7 @@ void train_wait (edict_t *self)
VectorClear (self->velocity);
// Knightmare added
if (!self->spawnflags & TRAIN_ROTATE_CONSTANT)
VectorClear (self->avelocity); //Knightmare added
VectorClear (self->avelocity);
// Lazarus: turn off animation for stationary trains
if (!strcmp(self->classname, "func_train"))
self->s.effects &= ~(EF_ANIM_ALL | EF_ANIM_ALLFAST);
@ -1970,7 +2415,7 @@ void train_yaw (edict_t *self)
if ((cur_yaw == idl_yaw) && (cur_pitch == idl_pitch) && (cur_roll == idl_roll) )
{
self->nextthink = level.time + FRAMETIME;
// if(self->enemy->movewith_next && (self->enemy->movewith_next->movewith_ent == self->enemy))
// if (self->enemy->movewith_next && (self->enemy->movewith_next->movewith_ent == self->enemy))
// set_child_movement(self->enemy);
return;
}
@ -2170,7 +2615,7 @@ void train_next (edict_t *self)
again:
if (!self->target)
{
// gi.dprintf ("train_next: no next target\n");
// gi.dprintf ("train_next: no next target\n");
self->s.sound = 0; // Knightmare added
return;
}
@ -2225,7 +2670,7 @@ again:
VectorCopy (dest, self->moveinfo.end_origin);
// Knightmare added
if(self->spawnflags & TRAIN_SPLINE)
if (self->spawnflags & TRAIN_SPLINE)
{
float speed;
int frames;
@ -2237,14 +2682,14 @@ again:
VectorSubtract(dest,self->s.origin,v);
self->moveinfo.distance = VectorLength(v);
frames = (int)(10 * self->moveinfo.distance/self->speed);
if(frames < 1) frames = 1;
if (frames < 1) frames = 1;
speed = (10*self->moveinfo.distance)/(float)frames;
self->moveinfo.speed = speed;
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
}
// Rroff rotating
if (self->spawnflags & TRAIN_ROTATE && !(ent->spawnflags & 2))
if ( (self->spawnflags & TRAIN_ROTATE) && !(ent->spawnflags & 2))
{
// Lazarus: No no no :-). This is measuring from the center
// of the func_train to the path_corner. Should
@ -2260,12 +2705,11 @@ again:
vectoangles2(v,angles);
self->ideal_yaw = angles[YAW];
self->ideal_pitch = angles[PITCH];
if(self->ideal_pitch < 0) self->ideal_pitch += 360;
if (self->ideal_pitch < 0) self->ideal_pitch += 360;
self->ideal_roll = ent->roll;
VectorClear(self->movedir);
self->movedir[1] = 1.0;
}
/* Lazarus: We don't want to do this... this would give an
// instantaneous change in pitch and roll and look
@ -2283,7 +2727,7 @@ again:
// end Rroff
// Lazarus:
if(self->spawnflags & TRAIN_ROTATE_CONSTANT)
if (self->spawnflags & TRAIN_ROTATE_CONSTANT)
{
self->avelocity[PITCH] = self->pitch_speed;
self->avelocity[YAW] = self->yaw_speed;
@ -2313,8 +2757,8 @@ void train_resume (edict_t *self)
Move_Calc (self, dest, train_wait);
self->spawnflags |= TRAIN_START_ON;
// Knighmare added from Lazarus
if(self->spawnflags & TRAIN_ROTATE_CONSTANT)
// Knightmare- added from Lazarus
if (self->spawnflags & TRAIN_ROTATE_CONSTANT)
{
self->avelocity[PITCH] = self->pitch_speed;
self->avelocity[YAW] = self->yaw_speed;
@ -2341,16 +2785,16 @@ void func_train_find (edict_t *self)
// Knightmare added
// Lazarus: trains can change speed at path_corners
if(ent->speed) {
if (ent->speed) {
self->speed = ent->speed;
self->moveinfo.speed = self->speed;
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
}
if(ent->pitch_speed)
if (ent->pitch_speed)
self->pitch_speed = ent->pitch_speed;
if(ent->yaw_speed)
if (ent->yaw_speed)
self->yaw_speed = ent->yaw_speed;
if(ent->roll_speed)
if (ent->roll_speed)
self->roll_speed = ent->roll_speed;
// Lazarus: spline stuff
@ -2376,6 +2820,7 @@ void func_train_find (edict_t *self)
VectorCopy (ent->s.origin, self->s.origin);
else
VectorSubtract (ent->s.origin, self->mins, self->s.origin);
VectorCopy (self->s.origin, self->s.old_origin);
gi.linkentity (self);
@ -2433,7 +2878,7 @@ void train_use (edict_t *self, edict_t *other, edict_t *activator)
{
// Back up a step
self->moveinfo.ratio -= self->moveinfo.speed * FRAMETIME / self->moveinfo.distance;
if(self->moveinfo.ratio < 0.)
if (self->moveinfo.ratio < 0.)
self->moveinfo.ratio = 0.;
}
// end Knightmare
@ -2528,8 +2973,8 @@ void SP_func_train (edict_t *self)
///////////
VectorAdd(self->s.origin,self->mins,self->monsterinfo.last_sighting);
// VectorCopy(self->s.origin,self->monsterinfo.last_sighting);
VectorAdd(self->s.origin, self->mins, self->monsterinfo.last_sighting);
// VectorCopy(self->s.origin, self->monsterinfo.last_sighting);
it = FindItem("Roam Navi");
@ -2814,7 +3259,7 @@ void door_secret_blocked (edict_t *self, edict_t *other)
return;
self->touch_debounce_time = level.time + 0.5;
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
// T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);

View file

@ -802,7 +802,7 @@ qboolean fire_hit (edict_t *self, vec3_t aim, int damage, int kick);
void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod);
void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod);
void fire_blaster (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper);
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius);
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean contact);
void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held);
void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
@ -867,7 +867,7 @@ void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer);
//
void PlayerNoise(edict_t *who, vec3_t where, int type);
void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent));
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire));
//
@ -1291,6 +1291,21 @@ struct edict_s
// RAFAEL
int orders;
//=========
//ROGUE
int plat2flags;
vec3_t offset;
vec3_t gravityVector;
edict_t *bad_area;
edict_t *hint_chain;
edict_t *monster_hint_chain;
edict_t *target_hint_chain;
int hint_chain_id;
// FIXME - debug help!
float lastMoveTime;
//ROGUE
//=========
// Knightmare added
char *usermodel;
int startframe;

View file

@ -189,7 +189,7 @@ void ClientEndServerFrames (void)
ent = g_edicts + 1 + i;
if (!ent->inuse || !ent->client)
continue;
if(!(ent->svflags & SVF_MONSTER))
if (!(ent->svflags & SVF_MONSTER))
ClientEndServerFrame (ent);
}
@ -212,95 +212,95 @@ void Get_NextMap()
char nextmap[MAX_QPATH];
int i;
if(!maplist->string) return;
if (!maplist->string) return;
sprintf(Buff,".\\%s\\3ZBMAPS.LST",gamepath->string);
Com_sprintf (Buff, sizeof(Buff), ".\\%s\\3ZBMAPS.LST",gamepath->string);
fp = fopen(Buff,"r");
if(fp == NULL) return;
if (fp == NULL) return;
//search section
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
if(Buff[0] != '[') continue;
if (Buff[0] != '[') continue;
i = 0;
while(1)
{
if(Buff[i] == ']') Buff[i] = 0;
if (Buff[i] == ']') Buff[i] = 0;
if(Buff[i] == 0) break;
if (Buff[i] == 0) break;
if(++i >= sizeof(Buff))
if (++i >= sizeof(Buff))
{
Buff[i - 1] = 0;
break;
}
}
//compare map section name
if(Q_stricmp (&Buff[1], maplist->string) == 0) break;
if (Q_stricmp (&Buff[1], maplist->string) == 0) break;
}
//search current mapname
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
if(Buff[0] == '[')
if (Buff[0] == '[')
{
if( firstflag )
if ( firstflag )
{
strcpy(nextmap,top);
Com_strcpy (nextmap, sizeof(nextmap),top);
goto SETNEXTMAP;
}
else goto NONEXTMAP;
}
if(Buff[0] == '\n') continue;
if (Buff[0] == '\n') continue;
sscanf(Buff,"%s",nextmap);
if(!firstflag)
if (!firstflag)
{
firstflag = true;
strcpy(top,nextmap);
Com_strcpy (top, sizeof(top), nextmap);
}
if(Q_stricmp (level.mapname, nextmap) == 0) break;
if (Q_stricmp (level.mapname, nextmap) == 0) break;
}
//search nextmap
while(1)
{
if(fgets( Buff, sizeof(Buff), fp ) == NULL)
if (fgets( Buff, sizeof(Buff), fp ) == NULL)
{
if( firstflag )
if ( firstflag )
{
strcpy(nextmap,top);
Com_strcpy (nextmap, sizeof(nextmap) ,top);
goto SETNEXTMAP;
}
else goto NONEXTMAP;
}
if(Buff[0] == '[')
if (Buff[0] == '[')
{
if( firstflag )
if ( firstflag )
{
strcpy(nextmap,top);
Com_strcpy (nextmap, sizeof(nextmap), top);
goto SETNEXTMAP;
}
else goto NONEXTMAP;
}
if(Buff[0] == '\n') continue;
if (Buff[0] == '\n') continue;
sscanf(Buff,"%s",nextmap);
break;
}
SETNEXTMAP:
strcpy(level.nextmap,nextmap);
Com_strcpy (level.nextmap, sizeof(level.nextmap), nextmap);
NONEXTMAP:
fclose(fp);
@ -510,9 +510,9 @@ void G_RunFrame (void)
//
// Bot Spawning
//
if(SpawnWaitingBots && !level.intermissiontime)
if (SpawnWaitingBots && !level.intermissiontime)
{
if(spawncycle < level.time)
if (spawncycle < level.time)
{
Bot_SpawnCall();
spawncycle = level.time + FRAMETIME * 10 + 0.01 * SpawnWaitingBots;
@ -520,7 +520,7 @@ void G_RunFrame (void)
}
else
{
if(spawncycle < level.time) spawncycle = level.time + FRAMETIME * 10;
if (spawncycle < level.time) spawncycle = level.time + FRAMETIME * 10;
}
//
// treat each object in turn
@ -548,9 +548,9 @@ void G_RunFrame (void)
}
//ctf job assign
if(ctf->value)
if (ctf->value)
{
if(ctfjob_update < level.time)
if (ctfjob_update < level.time)
{
//gi.bprintf(PRINT_HIGH,"Assigned!!!\n");
CTFJobAssign();
@ -558,13 +558,13 @@ void G_RunFrame (void)
}
}
//////////旗のスコアチェック
if(zigmode->value == 1)
if (zigmode->value == 1)
{
if(next_fragadd < level.time)
if (next_fragadd < level.time)
{
if(i > 0 && i <= maxclients->value && g_edicts[i].client)
if (i > 0 && i <= maxclients->value && g_edicts[i].client)
{
if(g_edicts[i].client->pers.inventory[ITEM_INDEX(zflag_item)])
if (g_edicts[i].client->pers.inventory[ITEM_INDEX(zflag_item)])
{
zflag_ent = NULL;
haveflag = true;
@ -576,23 +576,23 @@ void G_RunFrame (void)
//旗を持ってるとフラッグを足す
for ( j = 1 ; j <= maxclients->value ; j++)
{
if(g_edicts[j].inuse)
if (g_edicts[j].inuse)
{
if(OnSameTeam(&g_edicts[i],&g_edicts[j]))
if (OnSameTeam(&g_edicts[i],&g_edicts[j]))
g_edicts[j].client->resp.score += 1;
}
}
}
}
}
if(zflag_ent != NULL)
if (zflag_ent != NULL)
{
if(!zflag_ent->inuse)
if (!zflag_ent->inuse)
{
// item = FindItem("Zig Flag");
SelectSpawnPoint (ent, v, vv);
// VectorCopy (v, ent->s.origin);
if(ZIGDrop_Flag(ent,zflag_item))
if (ZIGDrop_Flag(ent,zflag_item))
{
VectorCopy (v, zflag_ent->s.origin);
}
@ -610,14 +610,14 @@ void G_RunFrame (void)
G_RunEntity (ent);
}
if(next_fragadd < level.time)
if (next_fragadd < level.time)
{
if(zflag_ent == NULL && !haveflag && !ctf->value
if (zflag_ent == NULL && !haveflag && !ctf->value
&& zigmode->value == 1 && zigflag_spawn == 2)
{
SelectSpawnPoint (ent, v, vv);
//VectorCopy (v, ent->s.origin);
if(ZIGDrop_Flag(ent,zflag_item))
if (ZIGDrop_Flag(ent,zflag_item))
{
VectorCopy (v, zflag_ent->s.origin);
}

View file

@ -365,7 +365,7 @@ void ThrowClientHead (edict_t *self, int damage)
if (self->client) // bodies in the queue don't have a client anymore
{
if(!(self->svflags & SVF_MONSTER))
if (!(self->svflags & SVF_MONSTER))
{
self->client->anim_priority = ANIM_DEATH;
self->client->anim_end = self->s.frame;
@ -1443,7 +1443,7 @@ void viper_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
/* e = self->movewith_next;
while(e) {
next = e->movewith_next;
if(e->solid == SOLID_NOT) {
if (e->solid == SOLID_NOT) {
e->nextthink = 0;
G_FreeEdict(e);
} else
@ -1489,9 +1489,9 @@ void SP_misc_viper (edict_t *ent)
VectorSet (ent->maxs, 32, 24, 16);
ent->takedamage = DAMAGE_YES;
ent->die = viper_die;
if(!ent->dmg)
if (!ent->dmg)
ent->dmg = 200;
if(!ent->mass)
if (!ent->mass)
ent->mass = 800;
}
else
@ -1668,9 +1668,9 @@ void SP_misc_strogg_ship (edict_t *ent)
VectorSet (ent->maxs, 72, 60, 38);
ent->takedamage = DAMAGE_YES;
ent->die = viper_die;
if(!ent->dmg)
if (!ent->dmg)
ent->dmg = 200;
if(!ent->mass)
if (!ent->mass)
ent->mass = 1200;
}
else
@ -2122,24 +2122,24 @@ void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_
//route update
if(chedit->value && CurrentIndex < MAXNODES && other == &g_edicts[1])
if (chedit->value && CurrentIndex < MAXNODES && other == &g_edicts[1])
{
gi.bprintf(PRINT_HIGH,"teleport!\n");
VectorCopy(self->s.origin,Route[CurrentIndex].Pt);
Route[CurrentIndex].ent = NULL;
Route[CurrentIndex].state = GRS_TELEPORT;
if(++CurrentIndex < MAXNODES)
if (++CurrentIndex < MAXNODES)
{
memset(&Route[CurrentIndex],0,sizeof(route_t));
Route[CurrentIndex].index = Route[CurrentIndex - 1].index +1;
}
}
if(other->svflags & SVF_MONSTER)
if (other->svflags & SVF_MONSTER)
{
if(other->client->zc.route_trace && other->client->zc.routeindex < CurrentIndex )
if (other->client->zc.route_trace && other->client->zc.routeindex < CurrentIndex )
{
if(Route[other->client->zc.routeindex].state == GRS_TELEPORT
if (Route[other->client->zc.routeindex].state == GRS_TELEPORT
/*&& Route[other->client->zc.routeindex].ent == self*/)
{
other->client->zc.routeindex++;
@ -2147,9 +2147,9 @@ void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_
}
if(other->client->zc.routeindex < CurrentIndex)
if (other->client->zc.routeindex < CurrentIndex)
{
if(Route[other->client->zc.routeindex].state == GRS_GRAPRELEASE)
if (Route[other->client->zc.routeindex].state == GRS_GRAPRELEASE)
{
other->client->zc.routeindex++;
//gi.bprintf(PRINT_HIGH,"Groff!\n");

View file

@ -65,7 +65,7 @@ void modelspawn_think (edict_t *self)
if (self->s.frame >= self->framenumbers)
{
self->s.frame = self->startframe;
if(self->spawnflags & ANIM_ONCE)
if (self->spawnflags & ANIM_ONCE)
{
model_spawn_use(self,world,world);
return;
@ -81,7 +81,7 @@ void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
{
self->svflags &= ~SVF_NOCLIENT;
self->delay = 0;
if(self->framenumbers > 1)
if (self->framenumbers > 1)
{
self->think = modelspawn_think;
self->nextthink = level.time + FRAMETIME;
@ -109,7 +109,7 @@ void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
e = self->movewith_next;
while(e) {
next = e->movewith_next;
if(e->solid == SOLID_NOT) {
if (e->solid == SOLID_NOT) {
e->nextthink = 0;
G_FreeEdict(e);
} else
@ -196,8 +196,8 @@ void SP_model_spawn (edict_t *ent)
}
}
// if(ent->movewith && (ent->solid == SOLID_BBOX))
// if(ent->movewith)
// if (ent->movewith && (ent->solid == SOLID_BBOX))
// if (ent->movewith)
// ent->movetype = MOVETYPE_PUSH;
if (ent->solid != SOLID_NOT)
@ -211,7 +211,7 @@ void SP_model_spawn (edict_t *ent)
else
{
if (ent->spawnflags & PLAYER_MODEL) {
if(!ent->usermodel || !strlen(ent->usermodel))
if (!ent->usermodel || !strlen(ent->usermodel))
ent->s.modelindex = MAX_MODELS-1;
else
{
@ -262,7 +262,7 @@ void SP_model_spawn (edict_t *ent)
ent->use = model_spawn_use;
}
if(!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
{
ent->think = modelspawn_think;
ent->nextthink = level.time + 2*FRAMETIME;

View file

@ -41,7 +41,7 @@ void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage,
void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype)
{
fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40);
fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40, false);
gi.WriteByte (svc_muzzleflash2);
gi.WriteShort (self - g_edicts);

View file

@ -41,18 +41,18 @@ void model_train_animator(edict_t *animator)
edict_t *train;
train = animator->owner;
if(!train || !train->inuse)
if (!train || !train->inuse)
{
G_FreeEdict(animator);
return;
}
if(Q_stricmp(train->classname,"model_train"))
if (Q_stricmp(train->classname,"model_train"))
{
G_FreeEdict(animator);
return;
}
animator->nextthink = level.time + FRAMETIME;
if(VectorLength(train->velocity) == 0)
if (VectorLength(train->velocity) == 0)
return;
train->s.frame++;
if (train->s.frame >= train->framenumbers)
@ -70,7 +70,7 @@ void SP_model_train (edict_t *self)
self->moveinfo.sound_middle = self->s.sound;
self->s.sound = 0;
if(!self->inuse) return;
if (!self->inuse) return;
// Reset some things from SP_model_spawn
self->delay = 0;
@ -82,7 +82,7 @@ void SP_model_train (edict_t *self)
self->takedamage = DAMAGE_YES;
}
if(self->framenumbers > self->startframe+1)
if (self->framenumbers > self->startframe+1)
{
edict_t *animator;
animator = G_Spawn();
@ -97,24 +97,24 @@ void SP_model_train (edict_t *self)
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
// already been checked in SP_model_spawn and are never re-used,
// so it's OK to overwrite those.
if(self->spawnflags & MTRAIN_ROTATE)
if (self->spawnflags & MTRAIN_ROTATE)
{
self->spawnflags &= ~MTRAIN_ROTATE;
self->spawnflags |= TRAIN_ROTATE;
}
if(self->spawnflags & MTRAIN_ROTATE_CONSTANT)
if (self->spawnflags & MTRAIN_ROTATE_CONSTANT)
{
self->spawnflags &= ~MTRAIN_ROTATE_CONSTANT;
self->spawnflags |= TRAIN_ROTATE_CONSTANT;
}
if( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
if ( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
{
self->spawnflags &= ~(TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT);
self->spawnflags |= TRAIN_SPLINE;
}
if(self->style == 3)
if (self->style == 3)
self->spawnflags |= TRAIN_ANIMATE; // 32
if(self->style == 4)
if (self->style == 4)
self->spawnflags |= TRAIN_ANIMATE_FAST; // 64
// TRAIN_SMOOTH forces trains to go directly to Move_Done from

347
3zb2/g_newfnc.c Normal file
View file

@ -0,0 +1,347 @@
#include "g_local.h"
//void plat_CalcMove (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
void fd_secret_move1(edict_t *self);
void fd_secret_move2(edict_t *self);
void fd_secret_move3(edict_t *self);
void fd_secret_move4(edict_t *self);
void fd_secret_move5(edict_t *self);
void fd_secret_move6(edict_t *self);
void fd_secret_done(edict_t *self);
/*
=============================================================================
SECRET DOORS
=============================================================================
*/
#define SEC_OPEN_ONCE 1 // stays open
#define SEC_1ST_LEFT 2 // 1st move is left of arrow
#define SEC_1ST_DOWN 4 // 1st move is down from arrow
#define SEC_NO_SHOOT 8 // only opened by trigger
#define SEC_YES_SHOOT 16 // shootable even if targeted
#define SEC_MOVE_RIGHT 32
#define SEC_MOVE_FORWARD 64
void fd_secret_use (edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *ent;
// gi.dprintf("fd_secret_use\n");
if (self->flags & FL_TEAMSLAVE)
return;
// trigger all paired doors
for (ent = self ; ent ; ent = ent->teamchain)
Move_Calc(ent, ent->moveinfo.start_origin, fd_secret_move1);
}
void fd_secret_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
// gi.dprintf("fd_secret_killed\n");
self->health = self->max_health;
self->takedamage = DAMAGE_NO;
if (self->flags & FL_TEAMSLAVE && self->teammaster && self->teammaster->takedamage != DAMAGE_NO)
fd_secret_killed (self->teammaster, inflictor, attacker, damage, point);
else
fd_secret_use (self, inflictor, attacker);
}
// Wait after first movement...
void fd_secret_move1(edict_t *self)
{
// gi.dprintf("fd_secret_move1\n");
self->nextthink = level.time + 1.0;
self->think = fd_secret_move2;
}
// Start moving sideways w/sound...
void fd_secret_move2(edict_t *self)
{
// gi.dprintf("fd_secret_move2\n");
Move_Calc(self, self->moveinfo.end_origin, fd_secret_move3);
}
// Wait here until time to go back...
void fd_secret_move3(edict_t *self)
{
// gi.dprintf("fd_secret_move3\n");
if (!(self->spawnflags & SEC_OPEN_ONCE))
{
self->nextthink = level.time + self->wait;
self->think = fd_secret_move4;
}
}
// Move backward...
void fd_secret_move4(edict_t *self)
{
// gi.dprintf("fd_secret_move4\n");
Move_Calc(self, self->moveinfo.start_origin, fd_secret_move5);
}
// Wait 1 second...
void fd_secret_move5(edict_t *self)
{
// gi.dprintf("fd_secret_move5\n");
self->nextthink = level.time + 1.0;
self->think = fd_secret_move6;
}
void fd_secret_move6(edict_t *self)
{
// gi.dprintf("fd_secret_move6\n");
Move_Calc(self, self->move_origin, fd_secret_done);
}
void fd_secret_done(edict_t *self)
{
// gi.dprintf("fd_secret_done\n");
if (!self->targetname || self->spawnflags & SEC_YES_SHOOT)
{
self->health = 1;
self->takedamage = DAMAGE_YES;
self->die = fd_secret_killed;
}
}
void secret_blocked(edict_t *self, edict_t *other)
{
if (!(self->flags & FL_TEAMSLAVE))
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 0, 0, MOD_CRUSH);
// if (time < self->attack_finished)
// return;
// self->attack_finished = time + 0.5;
// T_Damage (other, self, self, self->dmg);
}
/*
================
secret_touch
Prints messages
================
*/
void secret_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other->health <= 0)
return;
if (!(other->client))
return;
if (self->monsterinfo.attack_finished > level.time)
return;
self->monsterinfo.attack_finished = level.time + 2;
if (self->message)
{
gi.centerprintf (other, self->message);
// fixme - put this sound back??
// gi.sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
}
/*QUAKED func_door_secret2 (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot slide_right slide_forward
Basic secret door. Slides back, then to the left. Angle determines direction.
FLAGS:
open_once = not implemented yet
1st_left = 1st move is left/right of arrow
1st_down = 1st move is forwards/backwards
no_shoot = not implemented yet
always_shoot = even if targeted, keep shootable
reverse_left = the sideways move will be to right of arrow
reverse_back = the to/fro move will be forward
VALUES:
wait = # of seconds before coming back (5 default)
dmg = damage to inflict when blocked (2 default)
*/
void SP_func_door_secret2 (edict_t *ent)
{
vec3_t forward,right,up;
float lrSize, fbSize;
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
if (!ent->dmg)
ent->dmg = 2;
AngleVectors(ent->s.angles, forward, right, up);
VectorCopy(ent->s.origin, ent->move_origin);
VectorCopy(ent->s.angles, ent->move_angles);
G_SetMovedir (ent->s.angles, ent->movedir);
ent->movetype = MOVETYPE_PUSH;
ent->solid = SOLID_BSP;
gi.setmodel (ent, ent->model);
if(ent->move_angles[1] == 0 || ent->move_angles[1] == 180)
{
lrSize = ent->size[1];
fbSize = ent->size[0];
}
else if(ent->move_angles[1] == 90 || ent->move_angles[1] == 270)
{
lrSize = ent->size[0];
fbSize = ent->size[1];
}
else
{
gi.dprintf("Secret door not at 0,90,180,270!\n");
}
if(ent->spawnflags & SEC_MOVE_FORWARD)
VectorScale(forward, fbSize, forward);
else
{
VectorScale(forward, fbSize * -1 , forward);
}
if(ent->spawnflags & SEC_MOVE_RIGHT)
VectorScale(right, lrSize, right);
else
{
VectorScale(right, lrSize * -1, right);
}
if(ent->spawnflags & SEC_1ST_DOWN)
{
VectorAdd(ent->s.origin, forward, ent->moveinfo.start_origin);
VectorAdd(ent->moveinfo.start_origin, right, ent->moveinfo.end_origin);
}
else
{
VectorAdd(ent->s.origin, right, ent->moveinfo.start_origin);
VectorAdd(ent->moveinfo.start_origin, forward, ent->moveinfo.end_origin);
}
ent->touch = secret_touch;
ent->blocked = secret_blocked;
ent->use = fd_secret_use;
ent->moveinfo.speed = 50;
ent->moveinfo.accel = 50;
ent->moveinfo.decel = 50;
if (!ent->targetname || ent->spawnflags & SEC_YES_SHOOT)
{
ent->health = 1;
ent->max_health = ent->health;
ent->takedamage = DAMAGE_YES;
ent->die = fd_secret_killed;
}
if (!ent->wait)
ent->wait = 5; // 5 seconds before closing
gi.linkentity(ent);
}
// ==================================================
#define FWALL_START_ON 1
void force_wall_think(edict_t *self)
{
if(!self->wait)
{
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_FORCEWALL);
gi.WritePosition (self->pos1);
gi.WritePosition (self->pos2);
gi.WriteByte (self->style);
gi.multicast (self->offset, MULTICAST_PVS);
}
self->think = force_wall_think;
self->nextthink = level.time + 0.1;
}
void force_wall_use (edict_t *self, edict_t *other, edict_t *activator)
{
if(!self->wait)
{
self->wait = 1;
self->think = NULL;
self->nextthink = 0;
self->solid = SOLID_NOT;
gi.linkentity( self );
}
else
{
self->wait = 0;
self->think = force_wall_think;
self->nextthink = level.time + 0.1;
self->solid = SOLID_BSP;
KillBox(self); // Is this appropriate?
gi.linkentity (self);
}
}
/*QUAKED func_force_wall (1 0 1) ? start_on
A vertical particle force wall. Turns on and solid when triggered.
If someone is in the force wall when it turns on, they're telefragged.
start_on - forcewall begins activated. triggering will turn it off.
style - color of particles to use.
208: green, 240: red, 241: blue, 224: orange
*/
void SP_func_force_wall(edict_t *ent)
{
gi.setmodel (ent, ent->model);
ent->offset[0] = (ent->absmax[0] + ent->absmin[0]) / 2;
ent->offset[1] = (ent->absmax[1] + ent->absmin[1]) / 2;
ent->offset[2] = (ent->absmax[2] + ent->absmin[2]) / 2;
ent->pos1[2] = ent->absmax[2];
ent->pos2[2] = ent->absmax[2];
if(ent->size[0] > ent->size[1])
{
ent->pos1[0] = ent->absmin[0];
ent->pos2[0] = ent->absmax[0];
ent->pos1[1] = ent->offset[1];
ent->pos2[1] = ent->offset[1];
}
else
{
ent->pos1[0] = ent->offset[0];
ent->pos2[0] = ent->offset[0];
ent->pos1[1] = ent->absmin[1];
ent->pos2[1] = ent->absmax[1];
}
if(!ent->style)
ent->style = 208;
ent->movetype = MOVETYPE_NONE;
ent->wait = 1;
if(ent->spawnflags & FWALL_START_ON)
{
ent->solid = SOLID_BSP;
ent->think = force_wall_think;
ent->nextthink = level.time + 0.1;
}
else
ent->solid = SOLID_NOT;
ent->use = force_wall_use;
ent->svflags = SVF_NOCLIENT;
gi.linkentity(ent);
}

View file

@ -246,23 +246,23 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
//numplanes = 0;
//PON-CTF
i = false;
if(ctf->value)
if (ctf->value)
{
if(ent->client->ctf_grapple != NULL
if (ent->client->ctf_grapple != NULL
&& ent->client->ctf_grapplestate != CTF_GRAPPLE_STATE_FLY
/*&& ent->waterlevel <= 1*/) i = true;
}
if(!i){if(!ent->groundentity) i = true;}
if (!i){if (!ent->groundentity) i = true;}
//PON-CTF
if(!i/*ent->client*/)
if (!i/*ent->client*/)
{
if(!ent->client->zc.trapped
if (!ent->client->zc.trapped
&& !i)
{
numplanes = 0;
if(ent->waterlevel || (!ent->groundentity && ent->velocity[2] > 10 )) goto VELCX;
if (ent->waterlevel || (!ent->groundentity && ent->velocity[2] > 10 )) goto VELCX;
i =0;
if(/*ent->groundentity ||*/ ent->velocity[2] > 10) goto VELC;
if (/*ent->groundentity ||*/ ent->velocity[2] > 10) goto VELC;
}
}
@ -391,21 +391,22 @@ typedef struct
vec3_t angles;
float deltayaw;
} pushed_t;
pushed_t pushed[MAX_EDICTS], *pushed_p;
pushed_t pushed[MAX_EDICTS], *pushed_p;
edict_t *obstacle;
// Knightmare- added from Lazarus
void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, qboolean turn)
void MoveRiders (edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, qboolean turn)
{
int i;
edict_t *rider;
for(i=1, rider=g_edicts+i; i<=globals.num_edicts; i++, rider++) {
if((rider->groundentity == platform) && (rider != ignore)) {
for (i=1, rider=g_edicts+i; i<=globals.num_edicts; i++, rider++)
{
if ((rider->groundentity == platform) && (rider != ignore)) {
VectorAdd(rider->s.origin,move,rider->s.origin);
if (turn && (amove[YAW] != 0.)) {
if(!rider->client)
if (!rider->client)
rider->s.angles[YAW] += amove[YAW];
else
{
@ -416,13 +417,13 @@ void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, q
}
}
gi.linkentity(rider);
if(SV_TestEntityPosition(rider)) {
if (SV_TestEntityPosition(rider)) {
// Move is blocked. Since this is for riders, not pushees,
// it should be ok to just back the move for this rider off
VectorSubtract(rider->s.origin,move,rider->s.origin);
if(turn && (amove[YAW] != 0.)) {
if (turn && (amove[YAW] != 0.)) {
rider->s.angles[YAW] -= amove[YAW];
if(rider->client)
if (rider->client)
{
rider->client->ps.pmove.delta_angles[YAW] -= ANGLE2SHORT(amove[YAW]);
rider->client->ps.viewangles[YAW] -= amove[YAW];
@ -431,11 +432,12 @@ void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, q
gi.linkentity(rider);
} else {
// move this rider's riders
MoveRiders(rider,ignore,move,amove,turn);
MoveRiders (rider,ignore,move,amove,turn);
}
}
}
}
/*
============
RealBoundingBox
@ -454,27 +456,27 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
vec3_t p[8];
int i, j, k, j2, k4;
for(k=0; k<2; k++)
for (k=0; k<2; k++)
{
k4 = k*4;
if(k)
if (k)
p[k4][2] = ent->maxs[2];
else
p[k4][2] = ent->mins[2];
p[k4+1][2] = p[k4][2];
p[k4+2][2] = p[k4][2];
p[k4+3][2] = p[k4][2];
for(j=0; j<2; j++)
for (j=0; j<2; j++)
{
j2 = j*2;
if(j)
if (j)
p[j2+k4][1] = ent->maxs[1];
else
p[j2+k4][1] = ent->mins[1];
p[j2+k4+1][1] = p[j2+k4][1];
for(i=0; i<2; i++)
for (i=0; i<2; i++)
{
if(i)
if (i)
p[i+j2+k4][0] = ent->maxs[0];
else
p[i+j2+k4][0] = ent->mins[0];
@ -482,7 +484,7 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
}
}
AngleVectors(ent->s.angles,forward,left,up);
for(i=0; i<8; i++)
for (i=0; i<8; i++)
{
VectorScale(forward,p[i][0],f1);
VectorScale(left,-p[i][1],l1);
@ -493,7 +495,7 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
}
VectorCopy(p[0],mins);
VectorCopy(p[0],maxs);
for(i=1; i<8; i++)
for (i=1; i<8; i++)
{
mins[0] = min(mins[0],p[i][0]);
mins[1] = min(mins[1],p[i][1]);
@ -606,7 +608,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|| check->movetype == MOVETYPE_NOCLIP)
continue;
// if(check->movetype == MOVETYPE_STEP) M_CheckGround(check);
// if (check->movetype == MOVETYPE_STEP) M_CheckGround(check);
if (!check->area.prev)
continue; // not linked in anywhere
@ -652,13 +654,13 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
// Lazarus: if turn_rider is set, do it. We don't do this by default
// 'cause it can be a fairly drastic change in gameplay
if (turn && (check->groundentity == pusher)) {
if(!check->client)
if (!check->client)
{
check->s.angles[YAW] += amove[YAW];
}
else
{
if(amove[YAW] != 0.)
if (amove[YAW] != 0.)
{
check->client->ps.pmove.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
check->client->ps.viewangles[YAW] += amove[YAW];
@ -673,7 +675,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
// player is riding a MOVETYPE_PUSH
check->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
}
if(amove[PITCH] != 0.)
if (amove[PITCH] != 0.)
{
float delta_yaw;
float pitch = amove[PITCH];
@ -691,7 +693,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
// Lazarus: This is where we attempt to move check due to a rotation, WITHOUT embedding
// check in pusher (or anything else)
if((amove[PITCH] != 0) || (amove[YAW] != 0) || (amove[ROLL] != 0))
if ((amove[PITCH] != 0) || (amove[YAW] != 0) || (amove[ROLL] != 0))
{
// Argh! - always need to do this, except for pendulums
// if (pusher->movetype != MOVETYPE_PENDULUM)
@ -714,7 +716,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
VectorCopy(check->s.origin,org);
org[2] += 2*check->mins[2];
//tr = gi.trace(check->s.origin,vec3_origin,vec3_origin,org,check,MASK_SOLID);
//if(!tr.startsolid && tr.fraction < 1)
//if (!tr.startsolid && tr.fraction < 1)
// check->s.origin[2] = tr.endpos[2] - check->mins[2]
// + fabs(tr.plane.normal[0])*check->size[0]/2
// + fabs(tr.plane.normal[1])*check->size[1]/2;
@ -723,7 +725,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
// rotating pushers, trains still seem okay too but
// I haven't tested them thoroughly
tr = gi.trace(check->s.origin, check->mins, check->maxs, org, check, MASK_SOLID);
if(!tr.startsolid && tr.fraction < 1)
if (!tr.startsolid && tr.fraction < 1)
check->s.origin[2] = tr.endpos[2];
}
}
@ -756,7 +758,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
// Knightmare added
// Lazarus: Move check riders, and riders of riders, and... well, you get the pic
VectorAdd(move,move2,move3);
MoveRiders(check,NULL,move3,amove,turn);
MoveRiders (check,NULL,move3,amove,turn);
// end Knightmare
// impact?
continue;
@ -998,7 +1000,7 @@ void SV_Physics_Toss (edict_t *ent)
VectorScale (ent->velocity, FRAMETIME, move);
if(ent->classname[0] == 'R' && (ent->classname[6] == 'X' || ent->classname[6] == '3'))
if (ent->classname[0] == 'R' && (ent->classname[6] == 'X' || ent->classname[6] == '3'))
{
ent->groundentity = ent->union_ent;
ent->groundentity_linkcount = ent->union_ent->linkcount;
@ -1189,7 +1191,7 @@ void SV_Physics_Step (edict_t *ent)
ent->velocity[2] *= newspeed;
}
// if(ent->client){if(ent->client->ctf_grapple) if(ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_FLY) ent->velocity[2] = 0;}
// if (ent->client){if (ent->client->ctf_grapple) if (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_FLY) ent->velocity[2] = 0;}
if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0])
{
@ -1218,7 +1220,7 @@ void SV_Physics_Step (edict_t *ent)
if (ent->svflags & SVF_MONSTER)
{
if(!deathmatch->value) mask = MASK_MONSTERSOLID;
if (!deathmatch->value) mask = MASK_MONSTERSOLID;
else mask = MASK_BOTSOLIDX;//MASK_PLAYERSOLID;
}
else
@ -1238,13 +1240,13 @@ void SV_Physics_Step (edict_t *ent)
if (hitsound && !ent->waterlevel && speed > 0)
{
if( speed < 5 ) gi.sound (ent, 0, gi.soundindex("player/land1.wav"), 1, 1, 0);
else if( speed < 40 || ent->client == NULL)
if ( speed < 5 ) gi.sound (ent, 0, gi.soundindex("player/land1.wav"), 1, 1, 0);
else if ( speed < 40 || ent->client == NULL)
{
gi.sound (ent, 0, gi.soundindex("player/step3.wav"), 1, 1, 0);
// gi.bprintf(PRINT_HIGH,"level 1\n");
}
else if( speed < 60 )
else if ( speed < 60 )
{
gi.sound (ent, 0, gi.soundindex("*fall2.wav"), 1, 1, 0);
ent->pain_debounce_time = level.time + FRAMETIME * 10;

View file

@ -476,7 +476,7 @@ void WriteGame (char *filename, qboolean autosave)
gi.error ("Couldn't open %s", filename);
memset (str, 0, sizeof(str));
strcpy (str, __DATE__);
Com_strcpy (str, sizeof(str), __DATE__);
fwrite (str, sizeof(str), 1, f);
game.autosaved = autosave;

View file

@ -156,6 +156,11 @@ void SP_model_train_origin (edict_t *self);
void SP_misc_viper_origin (edict_t *ent);
void SP_misc_strogg_ship_origin (edict_t *ent);
void SP_misc_transport_origin (edict_t *ent);
// Knightmare- these are from Rogue
void SP_func_plat2 (edict_t *ent);
void SP_func_door_secret2 (edict_t *ent);
void SP_func_force_wall (edict_t *ent);
// end Knightmare
spawn_t spawns[] = {
@ -294,6 +299,10 @@ spawn_t spawns[] = {
{"misc_viper_origin", SP_misc_viper_origin},
{"misc_strogg_ship_origin", SP_misc_strogg_ship_origin},
{"misc_transport_origin", SP_misc_transport_origin},
// Knightmare- these are from Rogue
{"func_plat2", SP_func_plat2},
{"func_door_secret2", SP_func_door_secret2},
{"func_force_wall", SP_func_force_wall},
// end Knightmare
#if 0 // remove monster code
@ -1580,7 +1589,7 @@ void SP_worldspawn (edict_t *ent)
SetItemNames ();
if (st.nextmap)
strcpy (level.nextmap, st.nextmap);
Com_strcpy (level.nextmap, sizeof(level.nextmap), st.nextmap);
// make some data visible to the server

View file

@ -224,9 +224,9 @@ void SVCmd_WriteIP_f (void)
game = gi.cvar("game", "", 0);
if (!*game->string)
sprintf (name, "%s/listip.cfg", GAMEVERSION);
Com_sprintf (name, sizeof(name), "%s/listip.cfg", GAMEVERSION);
else
sprintf (name, "%s/listip.cfg", game->string);
Com_sprintf (name, sizeof(name), "%s/listip.cfg", game->string);
gi.cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name);
@ -297,7 +297,7 @@ void Svcmd_Test_f (void)
}
//chainファイルのセーブ
void SaveChain()
void SaveChain (void)
{
char name[256];
FILE *fpout;
@ -310,10 +310,12 @@ void SaveChain()
}
//とりあえずCTFだめ
if(ctf->value) sprintf(name,".\\%s\\chctf\\%s.chf",gamepath->string,level.mapname);
else sprintf(name,".\\%s\\chdtm\\%s.chn",gamepath->string,level.mapname);
if (ctf->value)
Com_sprintf (name, sizeof(name), ".\\%s\\chctf\\%s.chf",gamepath->string,level.mapname);
else
Com_sprintf (name, sizeof(name), ".\\%s\\chdtm\\%s.chn",gamepath->string,level.mapname);
fpout = fopen(name,"wb");
fpout = fopen(name, "wb");
if(fpout == NULL) gi.cprintf(NULL,PRINT_HIGH,"Can't open %s\n",name);
else
{

View file

@ -397,9 +397,11 @@ void vectoangles2 (vec3_t value1, vec3_t angles)
char *G_CopyString (char *in)
{
char *out;
size_t outSize;
out = gi.TagMalloc (strlen(in)+1, TAG_LEVEL);
strcpy (out, in);
outSize = strlen(in)+1;
out = gi.TagMalloc (outSize, TAG_LEVEL);
Com_strcpy (out, outSize, in);
return out;
}

View file

@ -48,7 +48,7 @@ static void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed)
VectorSet(vn,-8,-8,-8);
VectorSet(vx, 8, 8, 8);
VectorMA (start, 8192, dir, end);
VectorMA (start, WORLD_SIZE, dir, end); // was 8192
tr = gi.trace (start, vn, vx, end, self, MASK_SHOT);
if ((tr.ent) && tr.ent->client && Q_stricmp (tr.ent->classname, "player") == 0 && (tr.ent->health > 0))
{
@ -158,7 +158,12 @@ static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, i
r = crandom()*hspread;
u = crandom()*vspread;
VectorMA (start, 8192, forward, end);
// Knightmare- adjust spread for expanded world size
#ifdef KMQUAKE2_ENGINE_MOD
r *= (WORLD_SIZE / 8192);
u *= (WORLD_SIZE / 8192);
#endif
VectorMA (start, WORLD_SIZE, forward, end); // was 8192
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
@ -212,7 +217,12 @@ static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, i
AngleVectors (dir, forward, right, up);
r = crandom()*hspread*2;
u = crandom()*vspread*2;
VectorMA (water_start, 8192, forward, end);
// Knightmare- adjust spread for expanded world size
#ifdef KMQUAKE2_ENGINE_MOD
r *= (WORLD_SIZE / 8192);
u *= (WORLD_SIZE / 8192);
#endif
VectorMA (water_start, WORLD_SIZE, forward, end); // was 8192
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
}
@ -453,7 +463,7 @@ static void Grenade_Explode (edict_t *ent)
gi.multicast (ent->s.origin, MULTICAST_PHS);
G_FreeEdict (ent);
UpdateExplIndex(NULL);
UpdateExplIndex (NULL);
}
static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
@ -466,7 +476,7 @@ static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurfa
if (surf && (surf->flags & SURF_SKY))
{
G_FreeEdict (ent);
UpdateExplIndex(NULL);
UpdateExplIndex (NULL);
return;
}
@ -490,7 +500,27 @@ UpdateExplIndex(NULL);
Grenade_Explode (ent);
}
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius)
// Knightmare added
void ContactGrenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other == ent->owner)
return;
if (surf && (surf->flags & SURF_SKY))
{
G_FreeEdict (ent);
UpdateExplIndex (NULL);
return;
}
if (other->takedamage)
ent->enemy = other;
Grenade_Explode (ent);
}
// end Knightmare
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean contact)
{
edict_t *grenade;
vec3_t dir;
@ -513,14 +543,18 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s
VectorClear (grenade->maxs);
grenade->s.modelindex = gi.modelindex ("models/objects/grenade/tris.md2");
grenade->owner = self;
grenade->touch = Grenade_Touch;
// Knightmare- added contact explode
if (contact)
grenade->touch = ContactGrenade_Touch;
else
grenade->touch = Grenade_Touch;
grenade->nextthink = level.time + timer;
grenade->think = Grenade_Explode;
grenade->dmg = damage;
grenade->dmg_radius = damage_radius;
grenade->classname = "grenade";
UpdateExplIndex(grenade);
UpdateExplIndex (grenade);
gi.linkentity (grenade);
}
@ -585,7 +619,7 @@ void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *su
if (surf && (surf->flags & SURF_SKY))
{
G_FreeEdict (ent);
UpdateExplIndex(NULL);
UpdateExplIndex (NULL);
return;
}
@ -627,7 +661,7 @@ UpdateExplIndex(NULL);
gi.multicast (ent->s.origin, MULTICAST_PHS);
G_FreeEdict (ent);
UpdateExplIndex(NULL);
UpdateExplIndex (NULL);
}
void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage)
@ -656,7 +690,7 @@ void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed
rocket->s.sound = gi.soundindex ("weapons/rockfly.wav");
rocket->classname = "rocket";
UpdateExplIndex(rocket);
UpdateExplIndex (rocket);
if (self->client)
check_dodge (self, rocket->s.origin, dir, speed);
@ -787,7 +821,7 @@ void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick
int mask, i=0;
qboolean water;
VectorMA (start, 8192, aimdir, end);
VectorMA (start, WORLD_SIZE, aimdir, end); // was 8192
VectorCopy (start, from);
ignore = self;
water = false;
@ -845,7 +879,7 @@ void fire_sniperail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int
int mask;
qboolean water;
VectorMA (start, 8192, aimdir, end);
VectorMA (start, WORLD_SIZE, aimdir, end); // was 8192
VectorCopy (start, from);
ignore = self;
water = false;

View file

@ -55,7 +55,7 @@ static void SP_CreateCoopSpots (edict_t *self)
{
edict_t *spot;
if(Q_stricmp(level.mapname, "security") == 0)
if (Q_stricmp(level.mapname, "security") == 0)
{
spot = G_Spawn();
spot->classname = "info_player_coop";
@ -93,7 +93,7 @@ void SP_info_player_start(edict_t *self)
{
if (!coop->value)
return;
if(Q_stricmp(level.mapname, "security") == 0)
if (Q_stricmp(level.mapname, "security") == 0)
{
// invoke one of our gross, ugly, disgusting hacks
self->think = SP_CreateCoopSpots;
@ -126,7 +126,7 @@ void SP_info_player_coop(edict_t *self)
return;
}
if((Q_stricmp(level.mapname, "jail2") == 0) ||
if ((Q_stricmp(level.mapname, "jail2") == 0) ||
(Q_stricmp(level.mapname, "jail4") == 0) ||
(Q_stricmp(level.mapname, "mine1") == 0) ||
(Q_stricmp(level.mapname, "mine2") == 0) ||
@ -418,14 +418,14 @@ void TossClientWeapon (edict_t *self)
edict_t *enemy = NULL;
float spread;
if(self->enemy && self->enemy != self)
if (self->enemy && self->enemy != self)
{
if(self->enemy->classname[0] == 'p')
if (self->enemy->classname[0] == 'p')
{
VectorSubtract(self->s.origin,self->enemy->s.origin,v);
dist = VectorLength(v);
if(dist < 200) enemy = self->enemy;
if (dist < 200) enemy = self->enemy;
}
}
@ -463,7 +463,7 @@ void TossClientWeapon (edict_t *self)
drop = Drop_Item (self, item);
self->client->v_angle[YAW] += spread;
drop->spawnflags = DROPPED_PLAYER_ITEM;
if(enemy) enemy->client->zc.second_target = drop;
if (enemy) enemy->client->zc.second_target = drop;
}
if (quad)
@ -476,7 +476,7 @@ void TossClientWeapon (edict_t *self)
drop->touch = Touch_Item;
drop->nextthink = level.time + (self->client->quad_framenum - level.framenum) * FRAMETIME;
drop->think = G_FreeEdict;
if(enemy) enemy->client->zc.second_target = drop;
if (enemy) enemy->client->zc.second_target = drop;
}
// RAFAEL
if (quadfire)
@ -489,7 +489,7 @@ void TossClientWeapon (edict_t *self)
drop->touch = Touch_Item;
drop->nextthink = level.time + (self->client->quadfire_framenum - level.framenum) * FRAMETIME;
drop->think = G_FreeEdict;
if(enemy) enemy->client->zc.second_target = drop;
if (enemy) enemy->client->zc.second_target = drop;
}
}
@ -552,7 +552,7 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
if (!self->deadflag)
{
if(self->svflags & SVF_MONSTER)
if (self->svflags & SVF_MONSTER)
{
LookAtKiller (self, inflictor, attacker);
self->nextthink = level.time + FRAMETIME;
@ -568,16 +568,16 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
self->client->ps.pmove.pm_type = PM_DEAD;
ClientObituary (self, inflictor, attacker);
//ZOID
if(ctf->value) CTFFragBonuses(self, inflictor, attacker);
if (ctf->value) CTFFragBonuses(self, inflictor, attacker);
//ZOID
//旗持ってる場合は落とす
if(self->client->pers.inventory[ITEM_INDEX(zflag_item)])
if (self->client->pers.inventory[ITEM_INDEX(zflag_item)])
zflag_item->drop(self,zflag_item);
TossClientWeapon (self);
//ZOID
if(ctf->value)
if (ctf->value)
{
CTFPlayerResetGrapple(self);
CTFDeadDropFlag(self);
@ -713,7 +713,7 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
self->deadflag = DEAD_DEAD;
//routing last index move
if(chedit->value && self == &g_edicts[1]) Move_LastRouteIndex();
if (chedit->value && self == &g_edicts[1]) Move_LastRouteIndex();
gi.linkentity (self);
}
@ -753,7 +753,7 @@ void InitClientPersistant (gclient_t *client)
//ZOID
item = FindItem("Grapple");
if(ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
if (ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
//ZOID
client->pers.health = 100;
@ -1075,7 +1075,7 @@ void SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles)
}
VectorCopy (spot->s.origin, origin);
if(ent->svflags & SVF_MONSTER) origin[2] += 32;
if (ent->svflags & SVF_MONSTER) origin[2] += 32;
else origin[2] += 9;
VectorCopy (spot->s.angles, angles);
}
@ -1131,7 +1131,7 @@ void CopyToBodyQue (edict_t *ent)
body->s.number = body - g_edicts;
//強引にフレームセット
if(body->s.modelindex == skullindex || body->s.modelindex == headindex) body->s.frame = 0;
if (body->s.modelindex == skullindex || body->s.modelindex == headindex) body->s.frame = 0;
body->svflags = ent->svflags;
VectorCopy (ent->mins, body->mins);
@ -1145,7 +1145,7 @@ void CopyToBodyQue (edict_t *ent)
body->movetype = MOVETYPE_TOSS;//ent->movetype;
body->die = body_die;
if(ent->health < -40)
if (ent->health < -40)
{
body->takedamage = DAMAGE_NO;//DAMAGE_YES;
body->solid = SOLID_NOT;
@ -1438,16 +1438,16 @@ void PutClientInServer (edict_t *ent)
client->resp.spectator = false;
//ZOID
if(ctf->value)
if (ctf->value)
{
if (CTFStartClient(ent))
return;
}
//ZOID
//ponpoko
/* if(hokuto->value)
/* if (hokuto->value)
{
if(ZigockStartClient(ent))
if (ZigockStartClient(ent))
return;
}*/
//ponpoko
@ -1582,7 +1582,7 @@ void ClientUserinfoChanged (edict_t *ent, char *userinfo)
// check for malformed or illegal info strings
if (!Info_Validate(userinfo))
{
strcpy (userinfo, "\\name\\badinfo\\skin\\male/grunt");
Com_strcpy (userinfo, MAX_INFO_STRING, "\\name\\badinfo\\skin\\male/grunt"); // userinfo is always length of MAX_INFO_STRING
}
// set name
@ -1823,7 +1823,7 @@ void Get_Position ( edict_t *ent, vec3_t position )
void ChainPodThink (edict_t *ent)
{
if(ent->owner == NULL )return;
if (ent->owner == NULL )return;
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BFG_LASER);
@ -1831,9 +1831,9 @@ void ChainPodThink (edict_t *ent)
gi.WritePosition (ent->owner->s.origin);
gi.multicast (ent->s.origin, MULTICAST_PHS);
if(ent->target_ent != NULL)
if (ent->target_ent != NULL)
{
if(Q_stricmp (ent->target_ent->classname, "item_flag_team2") == 0)
if (Q_stricmp (ent->target_ent->classname, "item_flag_team2") == 0)
{
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BFG_LASER);
@ -1858,9 +1858,9 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
contents = CONTENTS_SOLID | CONTENTS_WINDOW;
if(!(ent->svflags & SVF_MONSTER))
if (!(ent->svflags & SVF_MONSTER))
{
if(ent->client->zc.waterstate)
if (ent->client->zc.waterstate)
{
VectorCopy(ent->mins,v1);
VectorCopy(ent->maxs,v2);
@ -1870,7 +1870,7 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
v2[0] += 4;
v2[1] += 4;*/
}
else if(!(ent->client->ps.pmove.pm_flags & PMF_DUCKED))
else if (!(ent->client->ps.pmove.pm_flags & PMF_DUCKED))
{
VectorSet(v1,-16,-16,-4);
VectorSet(v2,16,16,32);
@ -1891,17 +1891,17 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
}
rs_trace = gi.trace (ent->s.origin, v1, v2, p2 ,ent, contents );
if(rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid ) return true;
if (rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid ) return true;
if(ent->client->zc.route_trace && rs_trace.ent && (ent->svflags & SVF_MONSTER))
if (ent->client->zc.route_trace && rs_trace.ent && (ent->svflags & SVF_MONSTER))
{
//if(!rs_trace.ent->targetname)
if(!Q_stricmp(rs_trace.ent->classname, "func_door"))
//if (!rs_trace.ent->targetname)
if (!Q_stricmp(rs_trace.ent->classname, "func_door"))
{
if(rs_trace.ent->moveinfo.state == PSTATE_UP) return true;
if (rs_trace.ent->moveinfo.state == PSTATE_UP) return true;
else return false;
}
// if(!Q_stricmp(rs_trace.ent->classname, "func_train")) return true;
// if (!Q_stricmp(rs_trace.ent->classname, "func_train")) return true;
}
return false;
@ -1932,7 +1932,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
else
ground_speed = 0;
if( (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL) ||
if ( (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL) ||
(ent->client->chase_target != NULL) ||
(ground_speed > 0) )
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
@ -1943,19 +1943,19 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
impulse = ucmd->impulse;
if(impulse == 1) gi.bprintf(PRINT_HIGH,"%f\n",ent->s.origin[2]);
if (impulse == 1) gi.bprintf(PRINT_HIGH,"%f\n",ent->s.origin[2]);
//--------------------------------------------------------------------------------------
//Target check
if(ent->client->zc.first_target)
if (ent->client->zc.first_target)
{
if(!ent->client->zc.first_target->inuse) ent->client->zc.first_target = NULL;
else if(!ent->client->zc.first_target->deadflag) ent->client->zc.first_target = NULL;
if (!ent->client->zc.first_target->inuse) ent->client->zc.first_target = NULL;
else if (!ent->client->zc.first_target->deadflag) ent->client->zc.first_target = NULL;
}
//--------------------------------------------------------------------------------------
//get JumpMax
if(JumpMax == 0)
if (JumpMax == 0)
{
x = VEL_BOT_JUMP - ent->gravity * sv_gravity->value * FRAMETIME;
JumpMax = 0;
@ -1963,33 +1963,33 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
{
JumpMax += x * FRAMETIME;
x -= ent->gravity * sv_gravity->value * FRAMETIME;
if( x < 0 ) break;
if ( x < 0 ) break;
}
}
//route nodeput
j = 0;
if(ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) j = 1;
if (ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) j = 1;
if(!j && chedit->value && CurrentIndex < MAXNODES && !ent->deadflag && ent == &g_edicts[1])
if (!j && chedit->value && CurrentIndex < MAXNODES && !ent->deadflag && ent == &g_edicts[1])
{
if(targetindex > 0)
if (targetindex > 0)
{
if(ent->target_ent == NULL) return;
if (ent->target_ent == NULL) return;
other = ent->target_ent;
if(!TraceX(ent,other->s.origin))
if (!TraceX(ent,other->s.origin))
{
k = 0;
i = other->client->zc.routeindex;
while(1)
{
if(i + 1 >= CurrentIndex)
if (i + 1 >= CurrentIndex)
{
j = Route[i + 1].state;
if(j == GRS_ONTRAIN) if(Route[i + 1].ent->trainteam) break;
if (j == GRS_ONTRAIN) if (Route[i + 1].ent->trainteam) break;
Get_RouteOrigin(i + 1,v);
if(!TraceX(ent,other->s.origin))
if (!TraceX(ent,other->s.origin))
{
break;
}
@ -2020,45 +2020,46 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
Get_WaterState(ent);
i = false;
l = GRS_NORMAL;
if(CurrentIndex > 0) Get_RouteOrigin(CurrentIndex - 1,v);
if(!Route[CurrentIndex].index)
if (CurrentIndex > 0) Get_RouteOrigin(CurrentIndex - 1,v);
if (!Route[CurrentIndex].index)
{
VectorCopy(ent->s.origin,v);
old_ground = ent->groundentity;
//gi.bprintf(PRINT_HIGH,"1\n");
if(ent->groundentity)
if (ent->groundentity)
i = true;
}
else if(!TraceX(ent,v) /*&& ent->groundentity*/)
else if (!TraceX(ent,v) /*&& ent->groundentity*/)
{
VectorCopy(ent->s.old_origin,v);
//gi.bprintf(PRINT_HIGH,"2\n");
i = 3;
if(0/*ent->groundentity*/)
if (0/*ent->groundentity*/)
{
if(ent->groundentity->classname[0] == 'f') i = false;
if (ent->groundentity->classname[0] == 'f') i = false;
}
}
else if(ent->client->zc.waterstate != oldwaterstate)
else if (ent->client->zc.waterstate != oldwaterstate)
{
i = true;
if(ent->groundentity )
if (ent->groundentity )
{
if(!Q_stricmp(ent->groundentity->classname, "func_train")
if (!Q_stricmp(ent->groundentity->classname, "func_train")
|| !Q_stricmp(ent->groundentity->classname, "func_plat")
|| !Q_stricmp(ent->groundentity->classname, "func_plat2")
|| !Q_stricmp(ent->groundentity->classname, "func_door")) i = false;
}
if(ent->client->zc.waterstate > oldwaterstate) VectorCopy(ent->s.origin,v);
if (ent->client->zc.waterstate > oldwaterstate) VectorCopy(ent->s.origin,v);
else VectorCopy(ent->s.old_origin,v);
//gi.bprintf(PRINT_HIGH,"5\n");
}
else if(fabs(v[2] - ent->s.origin[2]) > 20)
else if (fabs(v[2] - ent->s.origin[2]) > 20)
{
if(ent->groundentity && ent->waterlevel < 2)
if (ent->groundentity && ent->waterlevel < 2)
{
k = true;
if(k)
if (k)
{
VectorCopy(ent->s.origin,v);
//gi.bprintf(PRINT_HIGH,"3\n");
@ -2067,7 +2068,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
else if(((/*ent->velocity[2] > 10 &&*/ !ent->groundentity && wasground == true)
else if (((/*ent->velocity[2] > 10 &&*/ !ent->groundentity && wasground == true)
|| (/*ent->velocity[2] < -0.5 &&*/ ent->groundentity && wasground == false))
&& Route[CurrentIndex - 1].state <= GRS_ITEMS)
{
@ -2076,21 +2077,22 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
VectorCopy(ent->s.old_origin,v);
v[2] -= 2;
rs_trace = gi.trace(ent->s.old_origin,ent->mins ,ent->maxs, v ,ent,MASK_PLAYERSOLID);
if(rs_trace.fraction != 1.0) j = true;
if (rs_trace.fraction != 1.0) j = true;
if(old_ground)
if (old_ground)
{
if(!Q_stricmp(old_ground->classname, "func_train")
if (!Q_stricmp(old_ground->classname, "func_train")
|| !Q_stricmp(old_ground->classname, "func_plat")
|| !Q_stricmp(old_ground->classname, "func_plat2")
|| !Q_stricmp(old_ground->classname, "func_door")) k = false;
}
if(!ent->groundentity /*&& j*/&& wasground == true && k)
if (!ent->groundentity /*&& j*/&& wasground == true && k)
{
VectorCopy(ent->s.old_origin,v);
//gi.bprintf(PRINT_HIGH,"6\n");
i = true;
}
else if(ent->groundentity /*&& !j*/&& wasground == false && k)
else if (ent->groundentity /*&& !j*/&& wasground == false && k)
{
// VectorSubtract(ent->s.origin)
@ -2100,13 +2102,14 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
else if(Route[CurrentIndex-1].index > 1)
else if (Route[CurrentIndex-1].index > 1)
{
k = true;
if(0/*old_ground*/)
if (0/*old_ground*/)
{
if(!Q_stricmp(old_ground->classname, "func_train")
if (!Q_stricmp(old_ground->classname, "func_train")
|| !Q_stricmp(old_ground->classname, "func_plat")
|| !Q_stricmp(old_ground->classname, "func_plat2")
|| !Q_stricmp(old_ground->classname, "func_door")) k = false;
}
Get_RouteOrigin(CurrentIndex - 1,min);
@ -2114,7 +2117,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
VectorSubtract(min,max,v);
x = Get_yaw(v);
VectorSubtract(ent->s.origin,/*Route[CurrentIndex-1].Pt*/ent->s.old_origin,v);
if(VectorLength(v) > 0 && Get_vec_yaw(v,x) > 45 && k )
if (VectorLength(v) > 0 && Get_vec_yaw(v,x) > 45 && k )
{
VectorCopy(ent->s.old_origin,v);
//gi.bprintf(PRINT_HIGH,"8\n");
@ -2122,17 +2125,17 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
if(ent->groundentity)
if (ent->groundentity)
{
if(ent->groundentity != old_ground)
if (ent->groundentity != old_ground)
{
other = old_ground;
old_ground = ent->groundentity;
if(!Q_stricmp(old_ground->classname, "func_plat"))
if ( !Q_stricmp(old_ground->classname, "func_plat") || !Q_stricmp(old_ground->classname, "func_plat2") )
{
if(old_ground->union_ent)
if (old_ground->union_ent)
{
if(old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
if (old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
{
//gi.bprintf(PRINT_HIGH,"plat put\n");
VectorCopy(old_ground->monsterinfo.last_sighting,v);
@ -2141,11 +2144,11 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
}
else if(!Q_stricmp(old_ground->classname, "func_train"))
else if (!Q_stricmp(old_ground->classname, "func_train"))
{
if(old_ground->union_ent)
if (old_ground->union_ent)
{
if(old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
if (old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
{
VectorCopy(old_ground->monsterinfo.last_sighting,v);
l = GRS_ONTRAIN;
@ -2153,12 +2156,12 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
}
else if(!Q_stricmp(old_ground->classname, "func_door"))
else if (!Q_stricmp(old_ground->classname, "func_door"))
{
k = false;
if(old_ground->targetname && old_ground->union_ent)
if (old_ground->targetname && old_ground->union_ent)
{
if(TraceX(ent,old_ground->union_ent->s.origin)
if (TraceX(ent,old_ground->union_ent->s.origin)
&& fabs(ent->s.origin[2] - old_ground->union_ent->s.origin[2]) < JumpMax)
{
VectorCopy(old_ground->monsterinfo.last_sighting,v);
@ -2168,7 +2171,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
else k = true;
}
else k = true;
if(k && i)
if (k && i)
{
i = 2;
old_ground = other;
@ -2176,33 +2179,34 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
}
if(old_ground)
if (old_ground)
{
if(old_ground->classname[0] == 'f' && i != 2)
if (old_ground->classname[0] == 'f' && i != 2)
{
if(!Q_stricmp(old_ground->classname, "func_train")
if (!Q_stricmp(old_ground->classname, "func_train")
|| !Q_stricmp(old_ground->classname, "func_plat")
|| !Q_stricmp(old_ground->classname, "func_plat2")
|| !Q_stricmp(old_ground->classname, "func_door")) i = false;
}
}
if(Route[CurrentIndex-1].index > 0 && i == true)
if (Route[CurrentIndex-1].index > 0 && i == true)
{
Get_RouteOrigin(CurrentIndex - 1,max);
VectorSubtract(max,v,vv);
if(VectorLength(vv) <= 32 ) i = false;
if (VectorLength(vv) <= 32 ) i = false;
}
if(l == GRS_ONTRAIN || l == GRS_ONPLAT || l == GRS_ONDOOR)
if (l == GRS_ONTRAIN || l == GRS_ONPLAT || l == GRS_ONDOOR)
{
if(Route[CurrentIndex - 1].ent == old_ground) i = false;
if (Route[CurrentIndex - 1].ent == old_ground) i = false;
}
if(i)
if (i)
{
if(l == GRS_NORMAL && ent->groundentity)
if (l == GRS_NORMAL && ent->groundentity)
{
if(!Q_stricmp(old_ground->classname, "func_rotating"))
if (!Q_stricmp(old_ground->classname, "func_rotating"))
{
l = GRS_ONROTATE;
// gi.bprintf(PRINT_HIGH,"On Rotate\n");
@ -2211,18 +2215,18 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
VectorCopy(v,Route[CurrentIndex].Pt);
Route[CurrentIndex].state = l;
if(l > GRS_ITEMS && l <= GRS_ONTRAIN) Route[CurrentIndex].ent = old_ground;
else if(l == GRS_ONDOOR) Route[CurrentIndex].ent = old_ground;
if (l > GRS_ITEMS && l <= GRS_ONTRAIN) Route[CurrentIndex].ent = old_ground;
else if (l == GRS_ONDOOR) Route[CurrentIndex].ent = old_ground;
if(l == GRS_ONTRAIN && old_ground->trainteam && old_ground->target_ent)
if (l == GRS_ONTRAIN && old_ground->trainteam && old_ground->target_ent)
{
if(!Q_stricmp(old_ground->target_ent->classname,"path_corner"))
if (!Q_stricmp(old_ground->target_ent->classname,"path_corner"))
VectorCopy(old_ground->target_ent->s.origin,Route[CurrentIndex].Tcourner);
//gi.bprintf(PRINT_HIGH,"get chain\n");
}
//when normal or items
if(++CurrentIndex < MAXNODES)
if (++CurrentIndex < MAXNODES)
{
gi.bprintf(PRINT_HIGH,"Last %i pod(s).\n",MAXNODES - CurrentIndex);
memset(&Route[CurrentIndex],0,sizeof(route_t)); //initialize
@ -2230,7 +2234,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
}
}
// VectorCopy(ent->s.origin,old_origin);
if(ent->groundentity != NULL) wasground = true;
if (ent->groundentity != NULL) wasground = true;
else wasground = false;
}

View file

@ -218,7 +218,8 @@ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
j = (int)strlen(entry);
if (stringlength + j > 1024)
break;
strcpy (string + stringlength, entry);
// strcpy (string + stringlength, entry);
Com_strcpy (string + stringlength, sizeof(string) - stringlength, entry);
stringlength += j;
}
@ -229,7 +230,8 @@ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
j = (int)strlen(entry);
if (stringlength + j > 1024)
break;
strcpy (string + stringlength, entry);
// strcpy (string + stringlength, entry);
Com_strcpy (string + stringlength, sizeof(string) - stringlength, entry);
stringlength += j;
}

View file

@ -69,7 +69,7 @@ void PMenu_Update(edict_t *ent)
hnd = ent->client->menu;
strcpy(string, "xv 32 yv 8 picn inventory ");
Com_strcpy (string, sizeof(string), "xv 32 yv 8 picn inventory ");
for (i = 0, p = hnd->entries; i < hnd->num; i++, p++) {
if (!p->text || !*(p->text))
@ -79,7 +79,8 @@ void PMenu_Update(edict_t *ent)
alt = true;
t++;
}
sprintf(string + strlen(string), "yv %d ", 32 + i * 8);
// sprintf (string + strlen(string), "yv %d ", 32 + i * 8);
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "yv %d ", 32 + i * 8);
if (p->align == PMENU_ALIGN_CENTER)
x = 196/2 - (int)strlen(t)*4 + 64;
else if (p->align == PMENU_ALIGN_RIGHT)
@ -87,15 +88,18 @@ void PMenu_Update(edict_t *ent)
else
x = 64;
sprintf(string + strlen(string), "xv %d ",
x - ((hnd->cur == i) ? 8 : 0));
// sprintf (string + strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
if (hnd->cur == i)
sprintf(string + strlen(string), "string2 \"\x0d%s\" ", t);
// sprintf (string + strlen(string), "string2 \"\x0d%s\" ", t);
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string2 \"\x0d%s\" ", t);
else if (alt)
sprintf(string + strlen(string), "string2 \"%s\" ", t);
// sprintf (string + strlen(string), "string2 \"%s\" ", t);
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string2 \"%s\" ", t);
else
sprintf(string + strlen(string), "string \"%s\" ", t);
// sprintf (string + strlen(string), "string \"%s\" ", t);
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string \"%s\" ", t);
alt = false;
}

View file

@ -139,17 +139,17 @@ qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
}
}
if((other->svflags & SVF_MONSTER) && ctf->value && other->client->zc.route_trace)
if ((other->svflags & SVF_MONSTER) && ctf->value && other->client->zc.route_trace)
{
if(!other->client->zc.first_target)
if (!other->client->zc.first_target)
{
for(i = 0;i < (5 * 2);i++)
for (i = 0;i < (5 * 2);i++)
{
if((other->client->zc.routeindex + i) >= CurrentIndex) break;
if(Route[other->client->zc.routeindex + i].state == GRS_GRAPSHOT)
if ((other->client->zc.routeindex + i) >= CurrentIndex) break;
if (Route[other->client->zc.routeindex + i].state == GRS_GRAPSHOT)
{
item = Fdi_GRAPPLE;//FindItem("Grapple");
if( other->client->pers.inventory[ITEM_INDEX(item)]) item->use(other,item);
if ( other->client->pers.inventory[ITEM_INDEX(item)]) item->use(other,item);
return true;
}
}
@ -160,11 +160,11 @@ qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
(other->client->pers.inventory[index] == 1) &&
( !deathmatch->value || other->client->pers.weapon == Fdi_BLASTER/*FindItem("blaster")*/ ) )
{
if(other->svflags & SVF_MONSTER) ent->item->use(other,ent->item);
if (other->svflags & SVF_MONSTER) ent->item->use(other,ent->item);
else other->client->newweapon = ent->item;
}
if(other->svflags & SVF_MONSTER
if (other->svflags & SVF_MONSTER
&& (other->client->pers.weapon == Fdi_BLASTER/*FindItem("blaster") */
|| other->client->pers.weapon == Fdi_GRENADES/*FindItem("Grenades")*/))
{
@ -188,19 +188,19 @@ void ShowGun(edict_t *ent)
{
int i,j;
if(!ent->client->pers.weapon)
if (!ent->client->pers.weapon)
{
ent->s.modelindex2 = 0;
return;
}
if(!vwep->value)
if (!vwep->value)
{
ent->s.modelindex2 = MAX_MODELS-1;
return;
}
j = Get_KindWeapon(ent->client->pers.weapon);
if(j == WEAP_GRAPPLE) j = WEAP_BLASTER;
if (j == WEAP_GRAPPLE) j = WEAP_BLASTER;
ent->s.modelindex2 = MAX_MODELS-1;
if (ent->client->pers.weapon)
@ -245,9 +245,9 @@ void ChangeWeapon (edict_t *ent)
ent->client->ps.gunframe = 0;
//lm ctf
mdl = ent->client->pers.weapon->view_model;
if(ctf->value == 2)
if (ctf->value == 2)
{
if(Q_stricmp (ent->client->pers.weapon->classname, "weapon_grapple") == 0)
if (Q_stricmp (ent->client->pers.weapon->classname, "weapon_grapple") == 0)
{
mdl = "models/weapons/v_hook/tris.md2";
}
@ -258,7 +258,7 @@ void ChangeWeapon (edict_t *ent)
// ### Hentai ### BEGIN
ent->client->anim_priority = ANIM_PAIN;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->s.frame = FRAME_crpain1;
ent->client->anim_end = FRAME_crpain4;
@ -333,9 +333,9 @@ void NoAmmoWeaponChange (edict_t *ent)
item = Fdi_SHOTGUN;//FindItem ("shotgun");
// return;
}
if(item == NULL) item = Fdi_BLASTER;//FindItem ("blaster");
if (item == NULL) item = Fdi_BLASTER;//FindItem ("blaster");
if(ent->svflags & SVF_MONSTER) item->use(ent,item);
if (ent->svflags & SVF_MONSTER) item->use(ent,item);
else ent->client->newweapon = item;
}
@ -417,10 +417,10 @@ void Use_Weapon (edict_t *ent, gitem_t *item)
if (item == ent->client->pers.weapon)
return;
if(ent->svflags & SVF_MONSTER)
if (ent->svflags & SVF_MONSTER)
{
if(ent->client->newweapon != NULL) return;
if(!Q_stricmp (item->pickup_name, "Blaster"))
if (ent->client->newweapon != NULL) return;
if (!Q_stricmp (item->pickup_name, "Blaster"))
{
ent->client->newweapon = item;
return;
@ -434,13 +434,13 @@ void Use_Weapon (edict_t *ent, gitem_t *item)
if (!ent->client->pers.inventory[ammo_index])
{
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
return;
}
if (ent->client->pers.inventory[ammo_index] < item->quantity)
{
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
return;
}
}
@ -457,7 +457,7 @@ void Use_Weapon2 (edict_t *ent, gitem_t *item)
gitem_t *nextitem;
int index;
if(ent->svflags & SVF_MONSTER)
if (ent->svflags & SVF_MONSTER)
{
Use_Weapon(ent,item);
return;
@ -544,7 +544,7 @@ void Drop_Weapon (edict_t *ent, gitem_t *item)
// see if we're already using it
if ( ((item == ent->client->pers.weapon) || (item == ent->client->newweapon))&& (ent->client->pers.inventory[index] == 1) )
{
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
return;
}
@ -564,9 +564,10 @@ A generic function to handle the basics of weapon thinking
#define FRAME_IDLE_FIRST (FRAME_FIRE_LAST + 1)
#define FRAME_DEACTIVATE_FIRST (FRAME_IDLE_LAST + 1)
void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire))
{
int n;
int current_weapon_index = ITEM_INDEX(ent->client->pers.weapon);
if (ent->client->weaponstate == WEAPON_DROPPING)
{
@ -575,10 +576,10 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
ChangeWeapon (ent);
return;
}// ### Hentai ### BEGIN
else if((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
{
ent->client->anim_priority = ANIM_REVERSE;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->s.frame = FRAME_crpain4+1;
ent->client->anim_end = FRAME_crpain1;
@ -614,10 +615,10 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
ent->client->weaponstate = WEAPON_DROPPING;
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
// ### Hentai ### BEGIN
if((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
{
ent->client->anim_priority = ANIM_REVERSE;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->s.frame = FRAME_crpain4+1;
ent->client->anim_end = FRAME_crpain1;
@ -636,9 +637,33 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
if (ent->client->weaponstate == WEAPON_READY)
{
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
// Knightmare- catch alt fire commands
if ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2)
{
ent->client->latched_buttons &= ~BUTTON_ATTACK;
// Add weapon alt attack handlers here
// Examples:
/* if (current_weapon_index == rl_index) // homing rocket switch
{
if (ent->client->pers.inventory[homing_index] > 0)
Use_Weapon (ent, FindItem("homing rocket launcher"));
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
ent->client->buttons &= ~BUTTONS_ATTACK;
return;
}
else if (current_weapon_index == hml_index)
{
if (ent->client->pers.inventory[rockets_index] > 0)
Use_Weapon (ent, FindItem("rocket launcher"));
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
ent->client->buttons &= ~BUTTONS_ATTACK;
return;
}*/
}
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
{
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
if ((!ent->client->ammo_index) ||
( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity))
{
@ -665,7 +690,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
ent->pain_debounce_time = level.time + 1;
}
/*if(ent->client->pers.weapon) gi.bprintf(PRINT_HIGH,"weapon %s %i\n"
/*if (ent->client->pers.weapon) gi.bprintf(PRINT_HIGH,"weapon %s %i\n"
,ent->client->pers.weapon->pickup_name
,ent->client->ammo_index);*/
// ,ent->client->pers.inventory[ITEM_INDEX(FindItem(ent->client->pers.weapon->ammo))]
@ -715,7 +740,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
//ZOID
CTFApplyHasteSound(ent);
//ZOID
fire (ent);
fire (ent, ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2));
break;
}
}
@ -729,7 +754,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
}
//ZOID
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire))
{
int oldstate = ent->client->weaponstate;
@ -810,7 +835,7 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
ent->client->grenade_time = level.time + 1.0;
if(ent->deadflag || ent->s.modelindex != MAX_MODELS-1) // VWep animations screw up corpses
if (ent->deadflag || ent->s.modelindex != MAX_MODELS-1) // VWep animations screw up corpses
{
return;
}
@ -849,9 +874,9 @@ void Weapon_Grenade (edict_t *ent)
if (ent->client->weaponstate == WEAPON_READY)
{
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
{
ent->client->latched_buttons &= ~BUTTON_ATTACK;
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
if (ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe = 1;
@ -902,7 +927,7 @@ void Weapon_Grenade (edict_t *ent)
ent->client->grenade_blew_up = true;
}
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
return;
if (ent->client->grenade_blew_up)
@ -946,7 +971,7 @@ GRENADE LAUNCHER
======================================================================
*/
void weapon_grenadelauncher_fire (edict_t *ent)
void weapon_grenadelauncher_fire (edict_t *ent, qboolean altfire)
{
vec3_t offset;
vec3_t forward, right;
@ -966,7 +991,7 @@ void weapon_grenadelauncher_fire (edict_t *ent)
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -1;
fire_grenade (ent, start, forward, damage, 600, 2.5, radius);
fire_grenade (ent, start, forward, damage, 600, 2.5, radius, altfire);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
@ -1003,7 +1028,7 @@ ROCKET
void fire_lockon_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
void Weapon_RocketLauncher_Fire (edict_t *ent)
void Weapon_RocketLauncher_Fire (edict_t *ent, qboolean altfire)
{
vec3_t offset, start;
vec3_t forward, right;
@ -1029,7 +1054,7 @@ void Weapon_RocketLauncher_Fire (edict_t *ent)
VectorSet(offset, 8, 8, ent->viewheight-8);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if(ent->client->zc.aiming != 4) fire_rocket (ent, start, forward, damage, 650, damage_radius, radius_damage);
if (ent->client->zc.aiming != 4) fire_rocket (ent, start, forward, damage, 650, damage_radius, radius_damage);
else
{
damage -= 20;//ロックオンは20ダメージ減り
@ -1054,20 +1079,20 @@ void Weapon_RocketLauncher_Fire (edict_t *ent)
}
//ロックオンロケットランチャー
void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
void Weapon_LockonRocketLauncher_Fire (edict_t *ent, qboolean altfire)
{
vec3_t tmp,out,aim,min,max;
vec_t f;
trace_t rs_trace;
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
{
ent->client->zc.lockon = false; //スナイパーにロックオン機能なし
if(ent->client->zc.aiming == 0)
if (ent->client->zc.aiming == 0)
{
gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/sshotr1b.wav"), 1, ATTN_NONE, 0);
ent->client->zc.aiming = 3;
if(ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
if (ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
ent->client->ps.fov = ent->client->zc.distance;//ズーム開始
}
@ -1077,20 +1102,20 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
VectorNormalize(aim);
VectorScale (aim, 8193, out);
VectorCopy(ent->s.origin,tmp);
if(ent->maxs[2] >= 32) tmp[2] += 22;
if (ent->maxs[2] >= 32) tmp[2] += 22;
else tmp[2] -= 2;
VectorAdd(tmp,out,aim);
rs_trace = gi.trace (tmp, min, max, aim,ent, MASK_PLAYERSOLID);
if(rs_trace.ent != NULL)
if (rs_trace.ent != NULL)
{
if(Q_stricmp (rs_trace.ent->classname, "player") == 0)
if (Q_stricmp (rs_trace.ent->classname, "player") == 0)
{
if(ctf->value)
if (ctf->value)
{
if(ent->client->resp.ctf_team != rs_trace.ent->client->resp.ctf_team)
if (ent->client->resp.ctf_team != rs_trace.ent->client->resp.ctf_team)
{
ent->client->zc.lockon = true;
if(ent->client->zc.first_target != rs_trace.ent)
if (ent->client->zc.first_target != rs_trace.ent)
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/locrloc.wav"), 1, ATTN_NORM, 0);
ent->client->zc.first_target = rs_trace.ent;
}
@ -1099,7 +1124,7 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
else
{
ent->client->zc.lockon = true;
if(ent->client->zc.first_target != rs_trace.ent)
if (ent->client->zc.first_target != rs_trace.ent)
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/locrloc.wav"), 1, ATTN_NORM, 0);
ent->client->zc.first_target = rs_trace.ent;
}
@ -1109,25 +1134,25 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
}
else ent->client->zc.first_target = NULL;
if(ent->client->zc.autozoom )
if (ent->client->zc.autozoom )
{
VectorSubtract(ent->s.origin,rs_trace.endpos,tmp);
f = VectorLength(tmp);
if(f < 200) ent->client->zc.distance = 90;
// else if(f < 300) ent->client->zc.distance = 75;
// else if(f < 500) ent->client->zc.distance = 60;
// else if(f < 800) ent->client->zc.distance = 45;
else if(f < 1300)
if (f < 200) ent->client->zc.distance = 90;
// else if (f < 300) ent->client->zc.distance = 75;
// else if (f < 500) ent->client->zc.distance = 60;
// else if (f < 800) ent->client->zc.distance = 45;
else if (f < 1300)
{
ent->client->zc.distance = 90 - (f - 200) / 14.6;//30;
}
else ent->client->zc.distance = 14;
if(ent->client->ps.fov != ent->client->zc.distance)
if (ent->client->ps.fov != ent->client->zc.distance)
{
f = ent->client->ps.fov - ent->client->zc.distance;
if(f > 15 || f < -15 )
if (f > 15 || f < -15 )
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/zoom.wav"), 1, ATTN_NORM, 0);
ent->client->ps.fov = ent->client->zc.distance;
@ -1136,7 +1161,7 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
return;
}
ent->client->zc.aiming = 4;
Weapon_RocketLauncher_Fire(ent);
Weapon_RocketLauncher_Fire (ent, altfire);
}
@ -1145,9 +1170,9 @@ void Weapon_RocketLauncher (edict_t *ent)
static int pause_frames[] = {25, 33, 42, 50, 0};
static int fire_frames[] = {5, 0};
if(!(ent->client->buttons & BUTTON_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
if (!(ent->client->buttons & BUTTONS_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
if(0/*1*/)
if (0/*1*/)
{
Weapon_Generic (ent, 4, 12, 50, 54, pause_frames, fire_frames, Weapon_LockonRocketLauncher_Fire);
}
@ -1183,7 +1208,7 @@ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, in
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 24, 8, ent->viewheight-8);
if(!(ent->svflags & SVF_MONSTER))
if (!(ent->svflags & SVF_MONSTER))
{
VectorAdd (offset, g_offset, offset);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
@ -1214,7 +1239,7 @@ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, in
}
void Weapon_Blaster_Fire (edict_t *ent)
void Weapon_Blaster_Fire (edict_t *ent, qboolean altfire)
{
int damage;
@ -1238,7 +1263,7 @@ void Weapon_Blaster (edict_t *ent)
}
void Weapon_HyperBlaster_Fire (edict_t *ent)
void Weapon_HyperBlaster_Fire (edict_t *ent, qboolean altfire)
{
float rotation;
vec3_t offset;
@ -1247,7 +1272,7 @@ void Weapon_HyperBlaster_Fire (edict_t *ent)
ent->client->weapon_sound = gi.soundindex("weapons/hyprbl1a.wav");
if (!(ent->client->buttons & BUTTON_ATTACK))
if (!(ent->client->buttons & BUTTONS_ATTACK))
{
ent->client->ps.gunframe++;
}
@ -1332,7 +1357,7 @@ MACHINEGUN / CHAINGUN
======================================================================
*/
void Machinegun_Fire (edict_t *ent)
void Machinegun_Fire (edict_t *ent, qboolean altfire)
{
int i;
vec3_t start;
@ -1342,7 +1367,7 @@ void Machinegun_Fire (edict_t *ent)
int kick = 2;
vec3_t offset;
if (!(ent->client->buttons & BUTTON_ATTACK))
if (!(ent->client->buttons & BUTTONS_ATTACK))
{
ent->client->machinegun_shots = 0;
ent->client->ps.gunframe++;
@ -1433,7 +1458,7 @@ void Weapon_Machinegun (edict_t *ent)
Weapon_Generic (ent, 3, 5, 45, 49, pause_frames, fire_frames, Machinegun_Fire);
}
void Chaingun_Fire (edict_t *ent)
void Chaingun_Fire (edict_t *ent, qboolean altfire)
{
int i;
int shots;
@ -1452,13 +1477,13 @@ void Chaingun_Fire (edict_t *ent)
if (ent->client->ps.gunframe == 5)
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK))
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTONS_ATTACK))
{
ent->client->ps.gunframe = 32;
ent->client->weapon_sound = 0;
return;
}
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK)
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTONS_ATTACK)
&& ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe = 15;
@ -1482,7 +1507,7 @@ void Chaingun_Fire (edict_t *ent)
shots = 1;
else if (ent->client->ps.gunframe <= 14)
{
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
shots = 2;
else
shots = 1;
@ -1559,7 +1584,7 @@ void Chaingun_Fire (edict_t *ent)
ent->client->pers.inventory[ent->client->ammo_index] -= shots;
}
void Gatringgun_Fire (edict_t *ent)
void Gatringgun_Fire (edict_t *ent, qboolean altfire)
{
int i;
int shots;
@ -1578,13 +1603,13 @@ void Gatringgun_Fire (edict_t *ent)
if (ent->client->ps.gunframe == 5)
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK))
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTONS_ATTACK))
{
ent->client->ps.gunframe = 32;
ent->client->weapon_sound = 0;
return;
}
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK)
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTONS_ATTACK)
&& ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe = 15;
@ -1608,7 +1633,7 @@ void Gatringgun_Fire (edict_t *ent)
shots = 10;//1;
else if (ent->client->ps.gunframe <= 14)
{
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
shots = 10;//2;
else
shots = 10;//1;
@ -1658,7 +1683,7 @@ void Gatringgun_Fire (edict_t *ent)
fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN);
}
if(is_silenced) u = 0.5;
if (is_silenced) u = 0.5;
else u = 1.0;
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/gatgf.wav"), u, ATTN_NORM, 0);
@ -1697,7 +1722,7 @@ void Weapon_Chaingun (edict_t *ent)
static int pause_frames[] = {38, 43, 51, 61, 0};
static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0};
if(0) Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Gatringgun_Fire);
if (0) Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Gatringgun_Fire);
else
{
Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Chaingun_Fire);
@ -1717,7 +1742,7 @@ SHOTGUN / SUPERSHOTGUN
======================================================================
*/
void weapon_shotgun_fire (edict_t *ent)
void weapon_shotgun_fire (edict_t *ent, qboolean altfire)
{
vec3_t start;
vec3_t forward, right;
@ -1777,7 +1802,7 @@ void Weapon_Shotgun (edict_t *ent)
}
void weapon_supershotgun_fire (edict_t *ent)
void weapon_supershotgun_fire (edict_t *ent, qboolean altfire)
{
vec3_t start;
vec3_t forward, right;
@ -1846,7 +1871,7 @@ RAILGUN
*/
void fire_sniperail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
void RSight_think(edict_t *ent)
void RSight_think (edict_t *ent)
{
trace_t rs_trace;
vec3_t aim,out,tmp;
@ -1854,7 +1879,7 @@ void RSight_think(edict_t *ent)
vec_t f;
if(ent->owner->client->ps.gunframe != 4 || ent->owner->deadflag)
if (ent->owner->client->ps.gunframe != 4 || ent->owner->deadflag)
{
G_FreeEdict(ent);
return;
@ -1865,37 +1890,37 @@ void RSight_think(edict_t *ent)
VectorNormalize(aim);
VectorScale (aim, 8193, out);
VectorCopy(ent->owner->s.origin,tmp);
if(ent->owner->maxs[2] >= 32) tmp[2] += 22;
if (ent->owner->maxs[2] >= 32) tmp[2] += 22;
else tmp[2] -= 2;
VectorAdd(tmp,out,aim);
rs_trace = gi.trace (tmp, min, max, aim,ent->owner, MASK_PLAYERSOLID);
VectorCopy(rs_trace.endpos,ent->s.origin);
ent->nextthink = level.time + FRAMETIME;
if(rs_trace.ent != NULL)
if (rs_trace.ent != NULL)
{
if(Q_stricmp (rs_trace.ent->classname, "player") == 0) return;//オートズーム反応せず
if (Q_stricmp (rs_trace.ent->classname, "player") == 0) return;//オートズーム反応せず
}
if(ent->owner->client->zc.autozoom )
if (ent->owner->client->zc.autozoom )
{
VectorSubtract(ent->s.origin,ent->owner->s.origin,tmp);
f = VectorLength(tmp);
if(f < 100) ent->owner->client->zc.distance = 90;
// else if(f < 300) ent->owner->client->zc.distance = 75;
// else if(f < 500) ent->owner->client->zc.distance = 60;
// else if(f < 800) ent->owner->client->zc.distance = 45;
else if(f < 1000)
if (f < 100) ent->owner->client->zc.distance = 90;
// else if (f < 300) ent->owner->client->zc.distance = 75;
// else if (f < 500) ent->owner->client->zc.distance = 60;
// else if (f < 800) ent->owner->client->zc.distance = 45;
else if (f < 1000)
{
ent->owner->client->zc.distance = 90 - (f - 100) / 12;//30;
}
else ent->owner->client->zc.distance = 15;
if(ent->owner->client->ps.fov != ent->owner->client->zc.distance)
if (ent->owner->client->ps.fov != ent->owner->client->zc.distance)
{
f = ent->owner->client->ps.fov - ent->owner->client->zc.distance;
if( f > 15 || f < -15)
if ( f > 15 || f < -15)
gi.sound (ent->owner, CHAN_AUTO, gi.soundindex("3zb/zoom.wav"), 1, ATTN_NORM, 0);
ent->owner->client->ps.fov = ent->owner->client->zc.distance;
@ -1904,7 +1929,7 @@ void RSight_think(edict_t *ent)
}
void weapon_railgun_fire (edict_t *ent)
void weapon_railgun_fire (edict_t *ent, qboolean altfire)
{
vec3_t start;
vec3_t forward, right;
@ -1940,7 +1965,7 @@ void weapon_railgun_fire (edict_t *ent)
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if(ent->client->zc.aiming == 0) fire_rail (ent, start, forward, damage, kick);
if (ent->client->zc.aiming == 0) fire_rail (ent, start, forward, damage, kick);
else
{
damage += 20;
@ -1965,14 +1990,14 @@ void weapon_railgun_fire (edict_t *ent)
ent->client->zc.aiming = 0; //ズーム不可
}
//スナイパー用railガン
void Weapon_SnipeRailgun (edict_t *ent)
void Weapon_SnipeRailgun (edict_t *ent, qboolean altfire)
{
edict_t *sight;
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
{
ent->client->zc.lockon = false; //スナイパーにロックオン機能なし
if( ent->client->zc.aiming == 0)
if ( ent->client->zc.aiming == 0)
{
//サイトの作成
sight = G_Spawn();
@ -1987,7 +2012,7 @@ void Weapon_SnipeRailgun (edict_t *ent)
sight->think = RSight_think;
sight->nextthink = level.time + FRAMETIME;
sight->classname = "rail sight";
if( ent->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
if ( ent->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
{
sight->s.frame = 1;
}
@ -1995,15 +2020,15 @@ void Weapon_SnipeRailgun (edict_t *ent)
gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/sshotr1b.wav"), 1, ATTN_NONE, 0);
ent->client->zc.aiming = 1;
if(ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
if (ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
ent->client->ps.fov = ent->client->zc.distance;//ズーム開始
}
return;
}
// if (ent->client->buttons & BUTTON_ATTACK) return;
// if (ent->client->buttons & BUTTONS_ATTACK) return;
ent->client->zc.aiming = 2;
weapon_railgun_fire(ent);
weapon_railgun_fire (ent, altfire);
}
void Weapon_Railgun (edict_t *ent)
@ -2011,9 +2036,9 @@ void Weapon_Railgun (edict_t *ent)
static int pause_frames[] = {56, 0};
static int fire_frames[] = {4, 0};
if(!(ent->client->buttons & BUTTON_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
if (!(ent->client->buttons & BUTTONS_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
if(0)
if (0)
{
Weapon_Generic (ent, 3, 18, 56, 61, pause_frames, fire_frames, Weapon_SnipeRailgun/*weapon_railgun_fire*/);
}
@ -2035,7 +2060,7 @@ BFG10K
======================================================================
*/
void weapon_bfg_fire (edict_t *ent)
void weapon_bfg_fire (edict_t *ent, qboolean altfire)
{
vec3_t offset, start;
vec3_t forward, right;
@ -2112,7 +2137,7 @@ void Weapon_BFG (edict_t *ent)
RipperGun
*/
void weapon_ionripper_fire (edict_t *ent)
void weapon_ionripper_fire (edict_t *ent, qboolean altfire)
{
vec3_t start;
vec3_t forward, right;
@ -2189,7 +2214,7 @@ void Weapon_Ionripper (edict_t *ent)
// Phalanx
//
void weapon_phalanx_fire (edict_t *ent)
void weapon_phalanx_fire (edict_t *ent, qboolean altfire)
{
vec3_t start;
vec3_t forward, right, up;
@ -2329,9 +2354,9 @@ void Weapon_Trap (edict_t *ent)
if (ent->client->weaponstate == WEAPON_READY)
{
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
{
ent->client->latched_buttons &= ~BUTTON_ATTACK;
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
if (ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe = 1;
@ -2387,7 +2412,7 @@ void Weapon_Trap (edict_t *ent)
ent->client->grenade_blew_up = true;
}
if (ent->client->buttons & BUTTON_ATTACK)
if (ent->client->buttons & BUTTONS_ATTACK)
return;
if (ent->client->grenade_blew_up)

View file

@ -1226,50 +1226,81 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
}
void Com_strcpy (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
if (!dest) {
Com_Printf ("Com_strcpy: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcpy: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcpy: dstSize < 1\n");
return;
return 0;
}
strncpy(dest, src, destSize-1);
// strncpy(dest, src, destSize-1);
// dest[destSize-1] = 0;
while (--decSize && *s)
*d++ = *s++;
*d = 0;
dest[destSize-1] = 0;
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
return (s - src - 1 + strlen(s));
else
return (s - src - 1); // returned count excludes NULL terminator
}
void Com_strcat (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcat (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
size_t dLen;
if (!dest) {
Com_Printf ("Com_strcat: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcat: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcat: dstSize < 1\n");
return;
return 0;
}
while (--destSize && *dest)
/* while (--destSize && *dest)
dest++;
if (destSize > 0) {
if (destSize > 0){
while (--destSize && *src)
*dest++ = *src++;
*dest = 0;
}*/
while (--decSize && *d)
d++;
dLen = d - dest;
if (decSize == 0)
return (dLen + strlen(s));
if (decSize > 0) {
while (--decSize && *s)
*d++ = *s++;
*d = 0;
}
dest[destSize-1] = 0;
return (dLen + (s - src)); // returned count excludes NULL terminator
}
/*

View file

@ -107,9 +107,25 @@ typedef enum {false, true} qboolean;
#define OLD_MAX_IMAGES 256
// end Knightmare
// Knightmare- hacked offsets for old demos
#define OLD_MAX_MODELS 256
#define OLD_MAX_SOUNDS 256
#define OLD_MAX_IMAGES 256
// end Knightmare
#define MAX_ITEMS 256
#define MAX_GENERAL (MAX_CLIENTS*2) // general config strings
// Knightmare- world size
#ifdef KMQUAKE2_ENGINE_MOD
#define MAX_WORLD_COORD (16384)
#define MIN_WORLD_COORD (-16384)
#else
#define MAX_WORLD_COORD (4096)
#define MIN_WORLD_COORD (-4096)
#endif
#define WORLD_SIZE (MAX_WORLD_COORD - MIN_WORLD_COORD)
// end Knightmare
// game print flags
#define PRINT_LOW 0 // pickup messages
@ -245,8 +261,9 @@ char *COM_Parse (char **data_p);
// data is an in/out parm, returns a parsed out token
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
void Com_strcpy (char *dest, size_t destSize, const char *src);
void Com_strcat (char *dest, size_t destSize, const char *src);
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
size_t Com_strcat (char *dest, size_t destSize, const char *src);
void Com_PageInMemory (byte *buffer, int size);
@ -572,6 +589,8 @@ typedef struct
//
#define BUTTON_ATTACK 1
#define BUTTON_USE 2
#define BUTTON_ATTACK2 4
#define BUTTONS_ATTACK (BUTTON_ATTACK | BUTTON_ATTACK2)
#define BUTTON_ANY 128 // any key whatsoever

View file

@ -1,5 +1,6 @@
This is the source code to the 3ZB2 support DLL for KMQuake2 .
It also supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod.
This is the source code to the 3ZB2 support DLL for KMQuake2.
It supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod,
and also the func_plat2 and func_door_secret2 entities from the Ground Zero mission pack.
Note this source code is under the original "Limited Program Source Code License" from id Software,
NOT the GPL. It should not be mixed with GPLed code.

24
awaken2/Readme_source.txt Normal file
View file

@ -0,0 +1,24 @@
==========================================
AWAKENING II: The Resurrection
v2.05
28-April-2007
==========================================
Site : http://awakening2.planetquake.gamespy.com/
IRC : irc://irc.accessirc.net/awaken2
------------------------------------------
Author : Chris "Musashi" Walker
E-mail : musashi@planetquake.com
Site : http://musashi.planetquake.gamespy.com/
===============================
NOTES
===============================
The original baseline for the mod was the CTF v1.50 source code (from way back in 1998). It's had a lot ripped out, and a lot more added - not just from me, but from several other authors as well who have kindly allowed their code to be used in this project.
Feel free to make use of the code as you like. All I ask is that you give credit where it is due if you use any of the code in your own applications or mods.
This source code is provided as-is with no warranties of any kind. If it causes something unspeakably evil to happen, you're on your own ;)

41
awaken2/action list.txt Normal file
View file

@ -0,0 +1,41 @@
-------------------------------------
BUGS:
-------------------------------------
-------------------------------------
TO DO - GENERAL:
-------------------------------------
-------------------------------------
TO DO - BOTS:
-------------------------------------
- CTF capability (check G_CTF refs).
- Use secondary mode of Gauss Pistol.
- Use Traps properly (eg. lay around power-items if no one around).
- Rocket-jumping ability.
- Shoot/avoid enemy C4 as well as traps, if touchbang or proximity set.
-------------------------------------
POTENTIAL CHANGES - GENERAL:
-------------------------------------
- Partial invisibility powerup -> Mystery Box.
- Jetpack powerup.
- New RL mode: nosecam (controllable rockets).
- Player stats for weapons (eg. accuracy, usage, etc).
- Location markers for maps.
- Top scores list for each map.
- Min/max player numbers in map file.
- Dynamically reduce 'max_traps_active' as player numbers increase.
- Banning list should be rechecked after server restart.
- Ability to go back to previous map in vote selection list.
-------------------------------------
POTENTIAL CHANGES - BOTS:
-------------------------------------
- Chasecam can be used on bots.
- Bots visible as clients in server info.
- If there are no players present in a game, spawn 'n' bots after 't' seconds (use cvars).
- Better camping algorithm.
- Better bot insults.

View file

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Awakening2", "awakening2_2008.vcproj", "{23875C27-60F4-4F16-B581-A32474963147}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{23875C27-60F4-4F16-B581-A32474963147}.Debug|Win32.ActiveCfg = Debug|Win32
{23875C27-60F4-4F16-B581-A32474963147}.Debug|Win32.Build.0 = Debug|Win32
{23875C27-60F4-4F16-B581-A32474963147}.Debug|x64.ActiveCfg = Debug|x64
{23875C27-60F4-4F16-B581-A32474963147}.Debug|x64.Build.0 = Debug|x64
{23875C27-60F4-4F16-B581-A32474963147}.Release|Win32.ActiveCfg = Release|Win32
{23875C27-60F4-4F16-B581-A32474963147}.Release|Win32.Build.0 = Release|Win32
{23875C27-60F4-4F16-B581-A32474963147}.Release|x64.ActiveCfg = Release|x64
{23875C27-60F4-4F16-B581-A32474963147}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load diff

7131
awaken2/g_bot.c Normal file

File diff suppressed because it is too large Load diff

281
awaken2/g_bot.h Normal file
View file

@ -0,0 +1,281 @@
// g_bot.h
//Maj/Pon++
#define MAXNODES 10000
#define MAXLINKPOD 6 // don't modify this
#define MAXBOTS 51 // number of name/skin entries
//skill[]
#define AIMACCURACY 0 // 0..9
#define AGGRESSION 1 // 0..9
#define COMBATSKILL 2 // 0..9
#define VRANGEVIEW 3 // 60..120 deg - Vertical view range
#define HRANGEVIEW 4 // 60..120 deg - Horizontal view range
#define PRIMARYWEAP 5 // 2..14 - 2 = Desert Eagle, 14 = AGM
typedef struct
{
vec3_t Pt;
union
{
vec3_t Tcorner; // target corner (train and grapple-shot only)
unsigned short linkpod[MAXLINKPOD]; // (GRS_NORMAL, GRS_ITEMS only 0 = do not select pod)
} podunion; //CW
edict_t *ent; // target ent
short index; // index num
short state; // targetstate
} route_t;
//CW++
// Avoid nameless unions for Linux compiler.
#define Tcorner podunion.Tcorner
#define linkpod podunion.linkpod
//CW--
extern route_t Route[MAXNODES]; // list of bot route nodes (from chn file)
extern int TotalRouteNodes; // number of used nodes in the 'Route[]' array
extern int CurrentIndex; // current node number that bot is at
extern float JumpMax; // max delta-height that bot can jump to //Pon
typedef struct
{
char netname[MAX_NAMELEN]; // netname //CW was 21
char skin[MAX_SKINLEN]; // skin //CW
int ingame; // spawned
int skill[6]; // parameters
qboolean camper; // TRUE => bot will camp certain items //CW++
} botinfo_t;
extern botinfo_t Bot[MAXBOTS+1];
void gi_cprintf(edict_t *ent, int printlevel, char *fmt, ...);
void gi_centerprintf(edict_t *ent, char *fmt, ...);
void gi_bprintf(int printlevel, char *fmt, ...);
void Use_Plat(edict_t *ent, edict_t *other, edict_t *activator);
void train_use(edict_t *self, edict_t *other, edict_t *activator);
void button_use(edict_t *self, edict_t *other, edict_t *activator);
void door_use(edict_t *self, edict_t *other, edict_t *activator);
void rotating_use(edict_t *self, edict_t *other, edict_t *activator);
void trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator);
void plat_go_up(edict_t *ent);
void SV_Physics_Step(edict_t *ent);
void path_corner_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
void DoRespawn(edict_t *ent);
void Cmd_Kill_f(edict_t *ent);
void ClientUserinfoChanged(edict_t *ent, char *userinfo);
void ClientDisconnect(edict_t *ent);
void Use_Item(edict_t *ent, edict_t *other, edict_t *activator);
// weapon functions
int WeapIndex(int weap);
void Weapon_DesertEagle(edict_t *self); //CW
void Weapon_GaussPistol(edict_t *self);
void Weapon_Jackhammer(edict_t *self);
void Weapon_Mac10(edict_t *self);
void Weapon_ESG(edict_t *self);
void Weapon_Flamethrower(edict_t *self);
void Weapon_RocketLauncher (edict_t *self);
void Weapon_C4(edict_t *self);
void Weapon_Trap(edict_t *self);
void Weapon_Railgun (edict_t *self);
void Weapon_ShockRifle(edict_t *self);
void Weapon_AGM(edict_t *self);
void Weapon_DiscLauncher(edict_t *self);
void Weapon_Chainsaw(edict_t *self);
void LoadBots(void); //CW
int GetKindWeapon(gitem_t *it);
void ReadRouteFile(void);
void droptofloor2(edict_t *ent);
void RespawnAllBots(void);
void TauntVictim(edict_t *ent, edict_t *victim);
void InsultVictim(edict_t *ent, edict_t *victim);
qboolean Pickup_Navi(edict_t *ent, edict_t *other);
void Bot_Think(edict_t *ent);
void CheckCampSite(edict_t *ent,edict_t *other);
void bFuncPlat(edict_t *ent);
void bFuncButton(edict_t *ent);
void bDoorBlocked(edict_t *ent);
void bFuncDoor(edict_t *ent);
void bFuncTrain(edict_t *ent);
void ResetGroundSlope(edict_t *ent);
void TraceAllSolid(edict_t *ent, vec3_t point, trace_t tr);
void CheckPrimaryWeapon(edict_t *ent, edict_t *other);
void G_FindTrainTeam(void);
void ForceRouteReset(edict_t *other);
void InitAllItems(void);
float SetBotXYSpeed(edict_t *ent, float *xyspeed);
void SetBotThink(edict_t *ent);
void CheckBotCrushed(edict_t *targ,edict_t *inflictor,int mod);
void Bot_CheckEnemy(gclient_t *client, edict_t *attacker, edict_t *targ, int mod);
void BotCheckGrapple(edict_t *ent);
//CW++
qboolean TraceX(edict_t *ent, vec3_t p2);
float Get_yaw(vec3_t vec);
float Get_vec_yaw(vec3_t vec, float yaw);
qboolean RemoveBot(edict_t *ent);
void SpawnNumBots_Safe(int numbots);
void RemoveNumBots_Safe(int numbots);
void Move_LastRouteIndex(void);
void Get_WaterState(edict_t *ent);
void Get_RouteOrigin(int index, vec3_t pos);
// behaviour variables/factors
#define BOT_FALLCHK_LOOPMAX 30
#define BOT_MAX_TAUNT_DIST 250
#define BOT_CAMP_PROB 0.5
#define BOT_TELE_MINHEALTH 20 // bot teleports if health falls below this during a fight...
#define BOT_TELE_ENEMYRANGE 480 // ...and enemy is within this range
#define BOT_TELE_FALLSPEED -400 // bot teleports if vertical velocity exceeds this towards an enviro hazard
#define BOT_CHICKENAIM_FACTOR 0.7 // aiming modification for chicken-shooting
#define BOT_DODGE_ENEMYRANGE 300 // range within which bot will try to dodge enemy shots
#define BOT_RUSH_ENEMYRANGE 400 // range within which bot will try to rush an enemy
#define BOT_PNOISE_SELF_DIST 700 // range within which bot will hear a personal noise (eg. jumping, pain, weapon firing)
#define BOT_PNOISE_IMPACT_DIST 300 // range within which bot will hear a weapon target noise (eg. bullet wall impacts)
#define BOT_PNOISE_RADIUS 300 // enemy's sound projected forward this much when testing for hidden sounds
//CW--
// moving speed ----------------------------------------------------
#define MOVE_SPD_DUCK 16
#define MOVE_SPD_WATER 16
#define MOVE_SPD_WALK 20
#define MOVE_SPD_RUN 30
#define MOVE_SPD_JUMP 30
#define VEL_BOT_JUMP 340 // jump velocity
#define VEL_BOT_WJUMP 340 // waterjump velocity
#define VEL_BOT_JUMP_NUDGE 20 // nudge-jump velocity
#define VEL_BOT_LADDERUP 200 // ladder-up velocity
#define VEL_BOT_WLADDERUP 200 // water ladder-up gain
#define VEL_BOT_ROCJUMP 500 // rocketjump velocity
// function's state P ----------------------------------------------
#define PSTATE_TOP 0
#define PSTATE_BOTTOM 1
#define PSTATE_UP 2
#define PSTATE_DOWN 3
#define PDOOR_TOGGLE 32
// height ----------------------------------------------------------
#define TOP_LIMIT 52
#define TOP_LIMIT_WATER 100
#define BOTTOM_LIMIT -52
#define BOTTOM_LIMIT_WATER -8190
#define BOTTOM_LIMITM -300
// waterstate ------------------------------------------------------
#define WAS_NONE 0
#define WAS_FLOAT 1
#define WAS_IN 2
// route chaining pod state ----------------------------------------
#define GRS_NORMAL 0
#define GRS_ONROTATE 1
#define GRS_TELEPORT 2
#define GRS_ITEMS 3
#define GRS_ONPLAT 4
#define GRS_ONTRAIN 5
#define GRS_ONDOOR 6
#define GRS_PUSHBUTTON 7
#define GRS_GRAPSHOT 20
#define GRS_GRAPHOOK 21
#define GRS_GRAPRELEASE 22
#define GRS_REDFLAG -10
#define GRS_BLUEFLAG -11
#define POD_LOCKFRAME 15
#define POD_RELEFRAME 20
#define MAX_SEARCH 12 // max search count / FRAMETIME
#define MAX_DOORSEARCH 10
// trace params ----------------------------------------------------
#define TRP_NOT 0 // don't trace
#define TRP_NORMAL 1 // trace normal
#define TRP_ANGLEKEEP 2 // trace and keep angle
#define TRP_MOVEKEEP 3 // angle and move vec keep but move
#define TRP_ALLKEEP 4 // don't move
// combat: aiming --------------------------------------------------
#define AIM_SFPOS 5.0 // aiming position offset scale-factor
#define AIM_SFANG_HITSCAN 0.75 // aimimg angle scale-factor: hitscan weapons
#define AIM_SFANG_PROJ 0.35 // aimimg angle scale-factor: projectile weapons
// movestate (general status list) ---------------------------------
#define STS_IDLE 0x00000000 // normal running
#define STS_LADDERUP 0x00000001 // climb the ladder
#define STS_TURBOJ 0x00000002 // turbo jump
#define STS_WATERJ 0x00000004 // water jump
#define STS_ROCJ 0x00000008 // rocket jumping
#define STS_TRIGPUSH 0x00001000 // hit a trigger_push //CW++
#define STS_AGMMOVE 0x00002000 // movement due to enemy AGM //CW++
#define STS_SJMASK (STS_ROCJ | STS_TURBOJ | STS_TRIGPUSH | STS_AGMMOVE | STS_WATERJ) //CW
#define STS_SJMASKEXW (STS_ROCJ | STS_TURBOJ | STS_TRIGPUSH | STS_AGMMOVE) //CW
// wait
#define STS_W_DONT 0x00000010 // don't wait for door/plat/train
#define STS_W_DOOROPEN 0x00000020 // wait for door open or down to bottom
#define STS_W_ONPLAT 0x00000040 // wait for plat or door reach to the top
#define STS_W_ONDOORUP 0x00000080 // wait for door reach to the top
#define STS_W_ONDOORDWN 0x00000100 // wait for door reach to the bottom
#define STS_W_ONTRAIN 0x00000200 // wait for door/plat/train reach to the top
#define STS_W_COMEPLAT 0x00000400 // wait for plat to come
#define STS_W_COMETRAIN 0x00000800 // wait for train to come
#define STS_WAITS (STS_W_DONT | STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN | STS_W_COMEPLAT | STS_W_COMETRAIN) //CW
#define STS_WAITSMASK (STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN | STS_W_COMEPLAT)
#define STS_WAITSMASK2 (STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONPLAT | STS_W_ONTRAIN)
#define STS_WAITSMASKCOM (STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN)
// battlemode (& bot skills)----------------------------------------
#define FIRE_NULL 0x00000000 // mode: none //CW++
#define FIRE_SLIDEMODE 0x00000001 // mode: slide with route
#define FIRE_PRESTAYFIRE 0x00000002 // mode/skill: stand still and fires (pre)
#define FIRE_STAYFIRE 0x00000004 // mode/skill: stand still and fires
#define FIRE_CHICKEN 0x00000008 // mode: chicken-shooting
#define FIRE_RUSH 0x00000010 // mode: rush attack
#define FIRE_ESTIMATE 0x00000020 // mode: fire in estimated enemy direction
#define FIRE_C4 0x00000040 // mode: using C4 //CW++
#define FIRE_JUMPROC 0x00000100 // skill: jump whilst firing rockets
#define FIRE_REFUGE 0x00000200 // mode/skill: retreat (back along route) whilst firing
#define FIRE_QUADUSE 0x00000400 // skill: select good weapons when Quadded
#define FIRE_C4USE 0x00000800 // skill: use C4 more competently //CW++
#define FIRE_AVOIDEXPLO 0x00001000 // mode/skill: try to avoid own RL & SR explosions
#define FIRE_AVOIDINVULN 0x00002000 // skill: avoid Invulnerable players
#define FIRE_DODGE 0x00004000 // mode/skill: dodge when being aimed at //CW++
#define FIRE_IGNORE 0x00008000 // mode/skill: ignore distant enemies
#define FIRE_SHIFT_R 0x10000000 // mode: strafe right
#define FIRE_SHIFT_L 0x20000000 // mode: strafe left
#define FIRE_SHIFT (FIRE_SHIFT_R | FIRE_SHIFT_L)
// combatstate ----------------------------------------------------
#define CTS_ENEM_NSEE 0x00000001 // have enemy but can't see
#define CTS_AGRBATTLE 0x00000002 // aggressive battle
#define CTS_ESCBATTLE 0x00000004 // escaping battle (item want)
#define CTS_HIPBATTLE 0x00000008 // high position battle (camp)
// combatstate: shooting
#define CTS_PREAIMING 0x00000010 // prepare for snipe or lockon
#define CTS_AIMING 0x00000020 // aimning for snipe or lockon
#define CTS_GRENADE 0x00000040 // hand grenade mode
#define CTS_JUMPSHOT 0x00000080 // jump shot
#define CTS_COMBS (CTS_AGRBATTLE | CTS_ESCBATTLE | CTS_HIPBATTLE | CTS_ENEM_NSEE)
//Maj/Pon--

504
awaken2/g_camera.c Normal file
View file

@ -0,0 +1,504 @@
// g_camera.c
//CW: This camera code is taken from the Lazarus mod source (version 2.1),
// which David Hyde released on 22-Sep-2001 for public use.
// See 'http://planetquake.com/lazarus' for more information.
#include "g_local.h"
void camera_off(edict_t *ent)
{
int i;
//CW++
edict_t *t_ent;
//CW--
if (!ent->client)
return;
if (!ent->client->spycam)
return;
if (ent->client->spycam->viewer == ent)
ent->client->spycam->viewer = NULL;
if (ent->client->spycam->svflags & SVF_MONSTER)
ent->client->spycam->svflags &= ~SVF_NOCLIENT;
//CW++
ent->client->frozen_framenum = ent->client->camplayer->client->frozen_framenum;
// If the fake entity is on fire, transfer the flame back to the player.
if (ent->client->camplayer->burning)
{
ent->burning = true;
ent->flame = ent->client->camplayer->flame;
ent->flame->enemy = ent;
ent->client->camplayer->flame = NULL;
ent->client->camplayer->burning = false;
}
// If the fake entity has been caught by a Trap, transfer the tractor beam to the player.
if (ent->client->camplayer->tractored)
{
ent->tractored = true;
ent->client->camplayer->tractored = false;
for (i = 0; i < globals.num_edicts; ++i)
{
t_ent = &g_edicts[i];
if ((t_ent->die == Trap_DieFromDamage) && (t_ent->enemy == ent->client->camplayer))
{
if (!t_ent->inuse)
continue;
t_ent->enemy = ent;
}
}
}
VectorCopy(ent->client->camplayer->s.origin, ent->s.old_origin);
//CW--
VectorCopy(ent->client->camplayer->s.origin, ent->s.origin);
gi.TagFree(ent->client->camplayer->client);
G_FreeEdict(ent->client->camplayer);
// set angles
ent->movetype = MOVETYPE_WALK;
ent->client->ps.pmove.pm_type = PM_NORMAL;
for (i = 0; i < 3; i++)
ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(ent->client->org_viewangles[i] - ent->client->resp.cmd_angles[i]);
VectorCopy(ent->client->org_viewangles, ent->client->resp.cmd_angles);
VectorCopy(ent->client->org_viewangles, ent->s.angles);
VectorCopy(ent->client->org_viewangles, ent->client->ps.viewangles);
VectorCopy(ent->client->org_viewangles, ent->client->v_angle);
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
ent->svflags &= ~SVF_NOCLIENT;
ent->clipmask = MASK_PLAYERSOLID;
ent->solid = SOLID_BBOX;
ent->client->camplayer = NULL;
ent->client->spycam = NULL;
gi.linkentity(ent);
}
void faker_animate(edict_t *self)
{
if ((self->s.frame < 0) || (self->s.frame > 39))
self->s.frame = 0;
else
{
self->s.frame++;
if (self->s.frame > 39)
self->s.frame = 0;
}
self->nextthink = level.time + FRAMETIME;
gi.linkentity(self);
}
void camera_on(edict_t *ent)
{
gclient_t *cl;
edict_t *faker;
edict_t *camera;
vec3_t forward;
vec3_t left;
vec3_t up;
if (!ent->client)
return;
if (!ent->client->spycam)
return;
// "viewer" can control camera aim (2nd player to come along and use camera cannot)
camera = ent->client->spycam;
if (!camera->viewer)
camera->viewer = ent;
// save current viewangles and restore them with camera_off
VectorCopy(ent->client->v_angle, ent->client->org_viewangles);
// copy over all important player data to fake player
ent->client->camplayer = G_Spawn();
faker = ent->client->camplayer;
faker->s.frame = ent->s.frame;
VectorCopy(ent->s.origin, faker->s.origin);
VectorCopy(ent->velocity, faker->velocity);
VectorCopy(ent->s.angles, faker->s.angles);
faker->s = ent->s;
faker->takedamage = DAMAGE_AIM;
faker->movetype = MOVETYPE_WALK;
faker->groundentity = ent->groundentity;
faker->viewheight = ent->viewheight;
faker->inuse = true;
faker->classname = "camplayer";
faker->mass = ent->mass;
faker->solid = SOLID_BBOX;
faker->deadflag = DEAD_NO;
faker->clipmask = MASK_PLAYERSOLID;
faker->health = ent->health;
faker->light_level = ent->light_level;
faker->think = faker_animate;
faker->nextthink = level.time + FRAMETIME;
//CW++
faker->style = ENT_ID_FAKER;
//CW--
VectorCopy(ent->mins, faker->mins);
VectorCopy(ent->maxs, faker->maxs);
// create a client so you can pick up items/be shot/etc while in camera
cl = (gclient_t *)gi.TagMalloc(sizeof(gclient_t), TAG_LEVEL); //CW
memset(cl, 0, sizeof(gclient_t));
ent->client->camplayer->client = cl;
ent->client->camplayer->target_ent = ent;
gi.linkentity(faker);
AngleVectors(camera->s.angles,forward,left,up);
VectorMA(camera->s.origin, camera->move_origin[0], forward, ent->s.origin);
VectorMA(ent->s.origin, -camera->move_origin[1], left, ent->s.origin);
VectorMA(ent->s.origin, camera->move_origin[2], up, ent->s.origin);
ent->movetype = MOVETYPE_NOCLIP;
ent->clipmask = 0;
ent->solid = SOLID_NOT;
VectorClear(ent->velocity);
ent->client->ps.gunindex = 0;
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
ent->svflags |= SVF_NOCLIENT;
if (ent->client->spycam->viewmessage)
gi_centerprintf(ent, ent->client->spycam->viewmessage);
//CW++
faker->delay = ent->delay;
// If the player is on fire, transfer the flame to the fake entity.
if (ent->burning)
{
faker->burning = true;
faker->flame = ent->flame;
faker->flame->enemy = faker;
ent->flame = NULL;
ent->burning = false;
}
// Mark the fake entity as being on the same team as the player.
faker->client->resp.ctf_team = ent->client->resp.ctf_team;
//CW--
}
edict_t *G_FindNextCamera(edict_t *camera, edict_t *monitor)
{
edict_t *next;
if (!monitor->target)
return NULL;
// If we already have a camera that's a monster, make it visible now.
if (camera && (camera->svflags & SVF_MONSTER))
{
camera->svflags &= ~SVF_NOCLIENT;
gi.linkentity(camera);
}
// First, determine if we're going to use the "count" to get the next camera,
// or just scan through the list of entities. If count for the first camera
// in the map is 0, then we'll just use the map order.
next = G_Find(NULL, FOFS(targetname), monitor->target);
if (!next)
return NULL;
if (!next->count)
{
if (camera)
{
next = camera;
next++;
}
else
next = g_edicts;
for ( ; next < &g_edicts[globals.num_edicts] ; next++)
{
if (next == camera)
continue;
if (!next->inuse)
continue;
if (next->deadflag == DEAD_DEAD)
continue;
if (!next->targetname)
continue;
// don't select "inactive" cameras
if (!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16))
continue;
if (!Q_stricmp(next->targetname, monitor->target))
goto found_one;
}
next = g_edicts;
for ( ; next < camera ; next++)
{
if (next == camera)
continue;
if (!next->inuse)
continue;
if (next->deadflag == DEAD_DEAD)
continue;
if (!next->targetname)
continue;
// don't select "inactive" cameras
if (!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16))
continue;
if (!Q_stricmp(next->targetname, monitor->target))
goto found_one;
}
}
else
{
int which;
int start;
if (camera)
{
which = camera->count + 1;
if (which > monitor->count)
which = 1;
}
else
which = 1;
start = which;
next = g_edicts + 1;
while (1)
{
if (next->targetname)
{
if (!Q_stricmp(next->targetname, monitor->target))
{
if (next->count == which)
{
if (!next->inuse || (next->deadflag == DEAD_DEAD) ||
(!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16)))
{
next = g_edicts;
which++;
if (which > monitor->count)
which = 1;
if (which == start)
return NULL;
}
else
goto found_one;
}
}
}
if (next == &g_edicts[globals.num_edicts-1])
{
next = g_edicts;
which++;
if (which > monitor->count)
which = 1;
if (which == start)
return NULL;
}
next++;
}
}
return NULL;
found_one:
if (!(monitor->spawnflags & 32) && (next->svflags & SVF_MONSTER))
next->svflags |= SVF_NOCLIENT;
return next;
}
edict_t *G_FindPrevCamera(edict_t *camera, edict_t *monitor)
{
edict_t *prev;
edict_t *newcamera = NULL; //CW
if (!monitor->target)
return NULL;
// If we already have a camera that's a monster, make it visible now.
if (camera && (camera->svflags & SVF_MONSTER))
{
camera->svflags &= ~SVF_NOCLIENT;
gi.linkentity(camera);
}
// First, determine if we're going to use the "count" to get the next camera,
// or just scan through the list of entities. If count for the first camera
// in the map is 0, then we'll just use the map order.
prev = G_Find(NULL, FOFS(targetname), monitor->target);
if (!prev)
return NULL;
if (!prev->count)
{
newcamera = NULL;
for (prev = g_edicts ; prev < &g_edicts[globals.num_edicts] ; prev++)
{
if (prev == camera)
{
if (newcamera)
goto found_one;
continue;
}
if (!prev->inuse)
continue;
if (prev->deadflag == DEAD_DEAD)
continue;
if (!prev->targetname)
continue;
// don't select "inactive" cameras
if (!Q_stricmp(prev->classname, "turret_breach") && (prev->spawnflags & 16))
continue;
if (!Q_stricmp(prev->targetname, monitor->target))
newcamera = prev;
}
goto found_one;
}
else
{
int which;
int start;
if (camera)
{
which = camera->count - 1;
if (which <= 0)
which = monitor->count;
}
else
which = monitor->count;
start = which;
prev = g_edicts + 1;
while (1)
{
if (prev->targetname)
{
if (!Q_stricmp(prev->targetname, monitor->target))
{
if (prev->count == which)
{
if (!prev->inuse || (prev->deadflag == DEAD_DEAD) ||
(!Q_stricmp(prev->classname, "turret_breach") && (prev->spawnflags & 16)))
{
prev = g_edicts;
which--;
if (which <= 0)
which = monitor->count;
if (which == start)
return NULL;
}
else
{
newcamera = prev;
goto found_one;
}
}
}
}
if (prev == &g_edicts[globals.num_edicts-1])
{
prev = g_edicts;
which--;
if (which <= 0)
which = monitor->count;
if (which == start)
return NULL;
}
prev++;
}
}
found_one:
if (!(monitor->spawnflags & 32) && (newcamera->svflags & SVF_MONSTER))
newcamera->svflags |= SVF_NOCLIENT;
return newcamera;
}
void use_camera(edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *target;
if (!activator->client)
return;
if (activator->client->spycam) // already using camera
return;
target = G_FindNextCamera(NULL, self);
if (!target)
return;
activator->client->spycam = target;
activator->client->monitor = self;
camera_on(activator);
}
void func_monitor_init(edict_t *self)
{
edict_t *camera;
self->count = 0;
camera = NULL;
while ((camera = G_Find(camera, FOFS(targetname), self->target)) != NULL)
self->count++;
if (!self->count)
self->s.effects = 0; // don't animate a func_monitor that has no cameras
}
void SP_func_monitor(edict_t *self)
{
if (!self->target)
{
gi.dprintf("func_monitor without a target at %s\n", vtos(self->s.origin));
G_FreeEdict(self);
return;
}
if (self->spawnflags & 8)
self->s.effects |= EF_ANIM_ALL;
if (self->spawnflags & 16)
self->s.effects |= EF_ANIM_ALLFAST;
gi.setmodel(self, self->model);
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_BSP;
self->use = use_camera;
self->think = func_monitor_init;
self->nextthink = level.time + (2.0 * FRAMETIME);
gi.linkentity(self);
}

338
awaken2/g_chase.c Normal file
View file

@ -0,0 +1,338 @@
// g_chase.c
//CW: This uses modified chase-cam code that was kindly sent in by
// Doug "Raven" Buckley; it was part of the Match Mod for Q2.
#include "g_local.h"
static char chase_modenames[][30] = {
"FreeCam",
"ChaseCam",
"FloatCam",
"EyeCam",
//CW++
"RearCam"
//CW--
};
void SwitchModeChaseCam(edict_t *ent)
{
// If chase cam is off, turn it on.
if (!ent->client->chase_target)
{
ToggleChaseCam(ent, NULL);
return;
}
// If we are in the last chasecam mode, turn it off.
if (ent->client->chase_mode == CHASE_LASTMODE)
{
ToggleChaseCam(ent, NULL);
return;
}
// Switch modes.
gi_cprintf(ent, PRINT_HIGH, "Now using %s.\n", chase_modenames[++ent->client->chase_mode]); //CW
}
void ToggleChaseCam(edict_t *ent, pmenu_t *p)
{
edict_t *e;
int i;
// If it's on, turn if off.
if (ent->client->chase_target)
{
gi_cprintf(ent, PRINT_HIGH, "ChaseCam deactivated.\n"); //CW
ent->client->chase_target = NULL;
PMenu_Close(ent);
return;
}
// If it's off, find a new chase target and track it.
for (i = 1; i <= (int)maxclients->value; i++)
{
e = g_edicts + i;
if (e->inuse && (e->solid != SOLID_NOT) && !e->isabot) //CW
{
ent->client->chase_mode = CHASE_FIRSTMODE;
ent->client->chase_target = e;
ent->client->update_chase = true;
PMenu_Close(ent);
gi_cprintf(ent, PRINT_HIGH, "ChaseCam activated (using %s mode).\n", chase_modenames[ent->client->chase_mode]); //CW
return;
}
}
gi_cprintf(ent, PRINT_HIGH, "ChaseCam - no target to chase!\n"); //CW
}
void UpdateChaseCam(edict_t *ent)
{
edict_t *targ;
edict_t *old;
vec3_t org;
vec3_t ownerv;
vec3_t goal;
vec3_t forward;
vec3_t right;
vec3_t oldgoal;
vec3_t angles;
trace_t trace;
int i;
int viewdist;
// If our chase target is gone, move to the next, or stop chasing if there are
// no more valid targets.
if (!ent->client->chase_target->inuse || ent->client->chase_target->client->spectator) //CW
{
old = ent->client->chase_target;
ChaseNext(ent);
if (ent->client->chase_target == old)
{
ent->client->chase_target = NULL;
ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
return;
}
}
targ = ent->client->chase_target;
VectorCopy(targ->s.origin, ownerv);
VectorCopy(ent->s.origin, oldgoal);
ownerv[2] += targ->viewheight;
// If in freecam mode, use that angle (SUMFUKA).
if (ent->client->chase_mode == CHASE_FREECAM)
{
for (i = 0; i < 3; i++)
angles[i] = ent->client->resp.cmd_angles[i] + SHORT2ANGLE(ent->client->ps.pmove.delta_angles[i]);
}
else
VectorCopy(targ->client->ps.viewangles, angles);
if (angles[PITCH] > 56.0)
angles[PITCH] = 56.0;
AngleVectors(angles, forward, right, NULL);
VectorNormalize(forward);
// View at different distances (default -60) (SUMFUKA).
viewdist = -60;
// Different distances...
if (ent->client->chase_mode == CHASE_FLOATCAM)
viewdist = -200;
else if (ent->client->chase_mode == CHASE_EYECAM)
viewdist = 20;
//CW++
else if (ent->client->chase_mode == CHASE_BUTTCAM)
viewdist = -30;
//CW--
VectorMA(ownerv, viewdist, forward, org);
if (org[2] < targ->s.origin[2] + -viewdist*0.6666667) //CW
org[2] = targ->s.origin[2] + -viewdist*0.6666667;
// Jump animation lifts.
if (!targ->groundentity)
org[2] += 16.0;
trace = gi.trace(ownerv, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
VectorCopy(trace.endpos, goal);
VectorMA(goal, 2.0, forward, goal);
// Pad for floors and ceilings.
VectorCopy(goal, org);
org[2] += 6.0;
trace = gi.trace(goal, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
if (trace.fraction < 1)
{
VectorCopy(trace.endpos, goal);
goal[2] -= 6.0;
}
VectorCopy(goal, org);
org[2] -= 6.0;
trace = gi.trace(goal, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
if (trace.fraction < 1)
{
VectorCopy(trace.endpos, goal);
goal[2] += 6.0;
}
// Using a free-move chasecam mode? (SUMFUKA).
if (ent->client->chase_mode == CHASE_FREECAM)
ent->client->ps.pmove.pm_type = PM_SPECTATOR;
else
ent->client->ps.pmove.pm_type = PM_FREEZE;
VectorCopy(goal, ent->s.origin);
// Only set angles if in a fixed viewangle mode (SUMFUKA).
if (ent->client->chase_mode != CHASE_FREECAM)
{
for (i = 0; i < 3; i++)
ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(targ->client->v_angle[i] - ent->client->resp.cmd_angles[i]);
//CW++
if (ent->client->chase_mode == CHASE_BUTTCAM)
{
ent->client->ps.viewangles[0] = -targ->client->ps.viewangles[0];
ent->client->ps.viewangles[1] = 180.0 + targ->client->ps.viewangles[1];
ent->client->ps.viewangles[2] = 0.0;
ent->client->v_angle[0] = -targ->client->ps.viewangles[0];
ent->client->v_angle[1] = 180.0 + targ->client->ps.viewangles[1];
ent->client->v_angle[2] = 0.0;
}
else
{
//CW--
VectorCopy(targ->client->v_angle, ent->client->ps.viewangles);
VectorCopy(targ->client->v_angle, ent->client->v_angle);
}
}
ent->viewheight = 0;
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
gi.linkentity(ent);
if ((!ent->client->showscores && !ent->client->menu && !ent->client->showinventory && !ent->client->showhelp &&
!(level.framenum & 31)) || ent->client->update_chase)
{
//CW++
char s[1024];
Com_sprintf(s, sizeof(s), "xv 0 yb -68 string2 \"Chasing %s\"", targ->client->pers.netname);
gi.WriteByte(svc_layout);
gi.WriteString(s);
gi.unicast(ent, false);
//CW--
ent->client->update_chase = false;
}
}
void ChaseNext(edict_t *ent)
{
edict_t *e;
int i;
if (!ent->client->chase_target)
return;
i = ent->client->chase_target - g_edicts;
do
{
i++;
if (i > (int)maxclients->value)
i = 1;
e = g_edicts + i;
if (!e->inuse)
continue;
if (e->solid != SOLID_NOT)
break;
} while (e != ent->client->chase_target);
ent->client->chase_target = e;
ent->client->update_chase = true;
}
void ChasePrev(edict_t *ent)
{
edict_t *e;
int i;
if (!ent->client->chase_target)
return;
i = ent->client->chase_target - g_edicts;
do
{
i--;
if (i < 1)
i = (int)maxclients->value;
e = g_edicts + i;
if (!e->inuse)
continue;
if (e->solid != SOLID_NOT)
break;
} while (e != ent->client->chase_target);
ent->client->chase_target = e;
ent->client->update_chase = true;
}
void ChaseRemoveTarget(edict_t *target)
{
edict_t *ent;
int i;
// Anyone chasing this target must no longer do so.
//CW++
for (i = 1; i <= (int)maxclients->value; i++)
{
ent = g_edicts + i;
if (!ent->inuse)
continue;
if (ent->client->spectator)
continue;
//CW--
if (ent->client->chase_target == target)
{
gi_cprintf(ent, PRINT_HIGH, "ChaseCam deactivated - target lost!\n"); //CW
ent->client->chase_target = NULL;
}
}
}
void GetChaseTarget(edict_t *ent)
{
edict_t *other;
int i;
for (i = 1; i <= (int)maxclients->value; i++)
{
other = g_edicts + i;
//CW++
if (!other->inuse)
continue;
if (other->client->spectator)
continue;
//CW--
ent->client->chase_target = other;
ent->client->update_chase = true;
UpdateChaseCam(ent);
return;
}
gi_centerprintf(ent, "No other players to chase."); //CW
}
void ChaseHelp(edict_t *ent)
{
gi_centerprintf(ent, "(use fire to change ChaseCam mode)\n(and [ or ] to change ChaseCam target)\n");
}

25
awaken2/g_chase.h Normal file
View file

@ -0,0 +1,25 @@
// g_chase.h
//CW: This code was kindly sent in by Doug "Raven" Buckley;
// it was used as part of The Match Mod for Q2.
#define CHASE_FREECAM 0
#define CHASE_CHASECAM 1
#define CHASE_FLOATCAM 2
#define CHASE_EYECAM 3
//CW++
#define CHASE_BUTTCAM 4
//CW--
#define CHASE_FIRSTMODE CHASE_FREECAM
#define CHASE_LASTMODE CHASE_BUTTCAM //CW
void ToggleChaseCam(edict_t *ent, pmenu_t *p);
void SwitchModeChaseCam(edict_t *ent);
void UpdateChaseCam(edict_t *ent);
void ChaseNext(edict_t *ent);
void ChasePrev(edict_t *ent);
void ChaseRemoveTarget(edict_t *target);
void ChaseHelp(edict_t *ent);

3280
awaken2/g_cmds.c Normal file

File diff suppressed because it is too large Load diff

678
awaken2/g_combat.c Normal file
View file

@ -0,0 +1,678 @@
// g_combat.c
#include "g_local.h"
/*
============
CanDamage
Returns true if the inflictor can directly damage the target. Used for
explosions and melee attacks.
============
*/
qboolean CanDamage(edict_t *targ, edict_t *inflictor)
{
vec3_t dest;
trace_t trace;
// bmodels need special checking because their origin is {0,0,0}.
if (targ->movetype == MOVETYPE_PUSH)
{
VectorAdd(targ->absmin, targ->absmax, dest);
VectorScale(dest, 0.5, dest);
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
if (trace.ent == targ)
return true;
return false;
}
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
VectorCopy(targ->s.origin, dest);
dest[0] += 15.0;
dest[1] += 15.0;
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
VectorCopy(targ->s.origin, dest);
dest[0] += 15.0;
dest[1] -= 15.0;
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
VectorCopy(targ->s.origin, dest);
dest[0] -= 15.0;
dest[1] += 15.0;
trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
VectorCopy(targ->s.origin, dest);
dest[0] -= 15.0;
dest[1] -= 15.0;
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
if (trace.fraction == 1.0)
return true;
return false;
}
/*
============
Killed
============
*/
void Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (targ->health < -999)
targ->health = -999;
targ->enemy = attacker;
if ((targ->movetype == MOVETYPE_PUSH) || (targ->movetype == MOVETYPE_STOP) || (targ->movetype == MOVETYPE_NONE))
{ // doors, triggers, etc
targ->die(targ, inflictor, attacker, damage, point);
return;
}
targ->die(targ, inflictor, attacker, damage, point);
}
/*
================
SpawnDamage
================
*/
void SpawnDamage(int type, vec3_t origin, vec3_t normal, int damage)
{
gi.WriteByte(svc_temp_entity);
gi.WriteByte(type);
gi.WritePosition(origin);
gi.WriteDir(normal);
gi.multicast(origin, MULTICAST_PVS);
}
/*
============
T_Damage
targ entity that is being damaged
inflictor entity that is causing the damage
attacker entity that caused the inflictor to damage targ
example: targ=monster, inflictor=rocket, attacker=player
dir direction of the attack
point point at which the damage is being inflicted
normal normal vector from that point
damage amount of damage being inflicted
knockback force to be applied against targ as a result of the damage
dflags these flags are used to control how T_Damage works
DAMAGE_RADIUS damage was indirect (from a nearby explosion)
DAMAGE_NO_ARMOR armor does not protect from this damage
DAMAGE_ENERGY damage is from an energy based weapon
DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles
DAMAGE_BULLET damage is from a bullet (used for ricochets)
DAMAGE_NO_PROTECTION kills godmode, armor, everything
============
*/
static int CheckPowerArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int dflags)
{
gclient_t *client;
int save;
int power_armor_type;
int index = 0; //CW
int damagePerCell;
int pa_te_type;
int power = 0; //CW
int power_used;
if (!damage)
return 0;
if (dflags & DAMAGE_NO_ARMOR)
return 0;
client = ent->client; //CW
//CW++
if (!client)
return 0;
//CW--
power_armor_type = PowerArmorType(ent);
if (power_armor_type != POWER_ARMOR_NONE)
{
index = ITEM_INDEX(FindItem("Cells"));
power = client->pers.inventory[index];
}
if (power_armor_type == POWER_ARMOR_NONE)
return 0;
if (!power)
return 0;
if (power_armor_type == POWER_ARMOR_SCREEN)
{
vec3_t vec;
vec3_t forward;
float dot;
// only works if damage point is in front
AngleVectors(ent->s.angles, forward, NULL, NULL);
VectorSubtract(point, ent->s.origin, vec);
VectorNormalize(vec);
dot = DotProduct(vec, forward);
if (dot <= 0.3)
return 0;
damagePerCell = 1;
pa_te_type = TE_SCREEN_SPARKS;
damage = (int)(0.333 * damage); //CW
}
else
{
if ((int)sv_gametype->value > G_FFA) //CW
damagePerCell = 1; // power armor is weaker in CTF, TDM & Assault
else
damagePerCell = 2;
pa_te_type = TE_SHIELD_SPARKS;
damage = (int)(0.667 * damage); //CW
}
save = power * damagePerCell;
if (!save)
return 0;
if (save > damage)
save = damage;
SpawnDamage(pa_te_type, point, normal, save);
ent->powerarmor_time = level.time + 0.2;
power_used = (int)(save / damagePerCell); //CW
if (client)
client->pers.inventory[index] -= power_used;
else
ent->monsterinfo.power_armor_power -= power_used;
return save;
}
static int CheckArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags)
{
gclient_t *client;
gitem_t *armor;
int save;
int index;
if (!damage)
return 0;
client = ent->client;
if (!client)
return 0;
if (dflags & DAMAGE_NO_ARMOR)
return 0;
index = ArmorIndex(ent);
if (!index)
return 0;
armor = GetItemByIndex(index);
if (dflags & DAMAGE_ENERGY)
save = ceil(((gitem_armor_t *)armor->info)->energy_protection * damage);
else
save = ceil(((gitem_armor_t *)armor->info)->normal_protection * damage);
if (save >= client->pers.inventory[index])
save = client->pers.inventory[index];
if (!save)
return 0;
client->pers.inventory[index] -= save;
SpawnDamage(te_sparks, point, normal, save);
return save;
}
qboolean CheckTeamDamage(edict_t *targ, edict_t *attacker)
{
//ZOID++
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker->client) //CW
{
if ((targ->client->resp.ctf_team == attacker->client->resp.ctf_team) && (targ != attacker))
return true;
}
//ZOID--
return false;
}
//CW++
qboolean CheckTurretTeamDamage(edict_t *targ, edict_t *attacker)
{
edict_t *player;
int i;
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker)
{
for (i = 0, player = g_edicts + 1; i < (int)maxclients->value; ++i, ++player)
{
if (player->client && (player->client->spycam == attacker))
{
if ((targ->client->resp.ctf_team == player->client->resp.ctf_team) && (targ != attacker))
return true;
}
}
}
return false;
}
//CW--
// /--- CW: was *targ
void T_Damage(edict_t *in_targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
{
gclient_t *client;
int take;
int save;
int asave;
int psave;
int te_sparks;
//DH++
edict_t *targ;
targ = in_targ;
if (!targ || !targ->inuse)
return;
//DH--
if (!targ->takedamage)
return;
//Maj++
CheckBotCrushed(targ, inflictor, mod);
//Maj--
//CW++
if ((mod == MOD_GAUSS_BEAM) && targ->client && (targ->client->antibeam_framenum > level.framenum))
{
gi.sound(targ, CHAN_ITEM, gi.soundindex("ctf/tech1.wav"), 1, ATTN_NORM, 0);
return;
}
targ->noise_index = 0;
//CW--
//DH++
// If targ is a fake player for the real player viewing camera, get that player
// out of the camera and do the damage to him (CW: 'style' abused with a hardcoded
// value so we don't have to to a slooow classname strcmp).
//CW++
if (targ->style == ENT_ID_FAKER)
//CW--
{
if (targ->target_ent && targ->target_ent->client && targ->target_ent->client->spycam)
{
//CW++
if (targ->target_ent->client->spycam == attacker) // shot self with turret
targ->target_ent->noise_index = 1; // abuse var so edict_t doesn't have to be extended
//CW--
if (attacker->enemy == targ)
{
attacker->enemy = targ->target_ent;
attacker->goalentity = NULL;
attacker->movetarget = NULL;
}
targ = targ->target_ent;
camera_off(targ);
}
else
return; // don't damage target_monitor camplayer
}
//DH--
//Maj++
if (targ != attacker) //CW...
{
if (CheckTeamDamage(targ, attacker))
damage = 0;
else
{
if (targ->client && !targ->isabot && attacker->client)
targ->client->current_enemy = attacker;
}
}
//Maj--
// friendly fire avoidance: if enabled you can't hurt teammates (but you can hurt yourself);
// knockback still occurs
meansOfDeath = mod;
client = targ->client;
if (dflags & DAMAGE_BULLET)
te_sparks = TE_BULLET_SPARKS;
else
te_sparks = TE_SPARKS;
VectorNormalize(dir);
//ZOID++
// strength tech
damage = CTFApplyStrength(attacker, damage);
//ZOID--
if (targ->flags & FL_NO_KNOCKBACK)
knockback = 0;
// figure momentum add
if (!(dflags & DAMAGE_NO_KNOCKBACK))
{
if (knockback && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP))
{
vec3_t kvel;
float mass;
if (targ->mass < 50.0)
mass = 50.0;
else
mass = (float)targ->mass;
if (client && (attacker == targ) && (inflictor->die != Trap_DieFromDamage)) //CW
//CW++
{
if (inflictor->die == C4_DieFromDamage)
VectorScale(dir, 2250.0 * ((float)knockback / mass), kvel); // the C4 jump hack
else
//CW--
VectorScale(dir, 1600.0 * ((float)knockback / mass), kvel); // the rocket jump hack
}
else
//CW++
{
if ((inflictor->touch == Rocket_Touch) || (inflictor->die == C4_DieFromDamage))
VectorScale(dir, sv_rocket_kick_scale->value * ((float)knockback / mass), kvel);
else
//CW--
VectorScale(dir, 500.0 * ((float)knockback / mass), kvel);
}
VectorAdd(targ->velocity, kvel, targ->velocity);
}
}
take = damage;
save = 0;
// check for godmode
if ((targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION))
{
take = 0;
save = damage;
SpawnDamage(te_sparks, point, normal, save);
}
// check for invincibility
if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION))
{
if (targ->pain_debounce_time < level.time)
{
gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
targ->pain_debounce_time = level.time + 2.0;
}
take = 0;
save = damage;
}
//ZOID++
//team armor protect
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker->client && //CW
(targ->client->resp.ctf_team == attacker->client->resp.ctf_team) &&
(targ != attacker) && ((int)dmflags->value & DF_ARMOR_PROTECT))
{
psave = asave = 0;
}
else if (CheckTurretTeamDamage(targ, attacker) && ((int)dmflags->value & DF_ARMOR_PROTECT))
{
psave = asave = 0;
}
else
{
//ZOID--
psave = CheckPowerArmor(targ, point, normal, take, dflags);
take -= psave;
asave = CheckArmor(targ, point, normal, take, te_sparks, dflags);
take -= asave;
}
//treat cheat/powerup savings the same as armor
asave += save;
//ZOID++
//resistance tech
take = CTFApplyResistance(targ, take);
//ZOID--
// team damage avoidance
if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage(targ, attacker))
return;
//CW++
if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTurretTeamDamage(targ, attacker))
return;
//CW--
//ZOID++
CTFCheckHurtCarrier(targ, attacker);
//ZOID--
// Do the damage.
if (take)
{
if ((targ->svflags & SVF_MONSTER) || client)
{
SpawnDamage(TE_BLOOD, point, normal, take);
Bot_CheckEnemy(client, attacker, targ, mod); //Maj++
}
else
SpawnDamage(te_sparks, point, normal, take);
if (!CTFMatchSetup())
//CW++
{
// D89 (needle) power-up: damage is halved.
if (client && (client->needle_framenum > level.framenum))
take = (int)(0.5 * take);
//CW--
targ->health = targ->health - take;
//CW++
// Awakening (siphon) power-up: attacker gets health equal to damage inflicted (unless it's us).
if (client && attacker->client)
{
if (attacker->client->siphon_framenum > level.framenum)
{
if ((targ != attacker) && (attacker->health < (int)sv_health_max_siphon->value))
{
attacker->health += take + ((targ->health < 0)?targ->health:0);
gi.sound(attacker, CHAN_ITEM, gi.soundindex("items/siphon3.wav"), 1, ATTN_NORM, 0);
if (attacker->health > (int)sv_health_max_siphon->value)
attacker->health = (int)sv_health_max_siphon->value;
}
}
if ((mod == MOD_AGM_DISRUPT) && (attacker->health < (int)sv_health_max_siphon->value))
{
attacker->health += (int)(sv_agm_disrupt_siphon->value * (take + ((targ->health < 0)?targ->health:0)));
gi.sound(attacker, CHAN_ITEM, gi.soundindex("parasite/paratck3.wav"), 1, ATTN_NORM, 0);
if (attacker->health > (int)sv_health_max_siphon->value)
attacker->health = (int)sv_health_max_siphon->value;
}
}
}
//CW--
if (targ->health < 1) //CW
{
if ((targ->svflags & SVF_MONSTER) || client)
targ->flags |= FL_NO_KNOCKBACK;
Killed(targ, inflictor, attacker, take, point);
return;
}
}
if (client)
{
if (!(targ->flags & FL_GODMODE) && take && !CTFMatchSetup())
targ->pain(targ, attacker, knockback, take);
}
else if (take)
{
if (targ->pain)
targ->pain(targ, attacker, knockback, take);
}
// add to the damage inflicted on a player this frame
// the total will be turned into screen blends and view angle kicks at the end of the frame
if (client)
{
client->damage_parmor += psave;
client->damage_armor += asave;
client->damage_blood += take;
client->damage_knockback += knockback;
VectorCopy(point, client->damage_from);
}
}
/*
============
T_RadiusDamage
============
*/
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
{
edict_t *ent = NULL;
vec3_t v;
vec3_t dir;
float points;
//CW++
edict_t *targ;
//CW--
while ((ent = FindRadius(ent, inflictor->s.origin, radius)) != NULL)
{
if (ent == ignore)
continue;
if (!ent->takedamage)
continue;
//CW++
// For detonating C4 bundles, don't apply radius damage to other C4 bundles belonging to the player.
if (inflictor->die == C4_DieFromDamage)
{
if ((ent->die == C4_DieFromDamage) && (ent->owner == inflictor->owner))
continue;
}
//CW--
VectorAdd(ent->mins, ent->maxs, v);
VectorMA(ent->s.origin, 0.5, v, v);
VectorSubtract(inflictor->s.origin, v, v);
points = damage - (0.5 * VectorLength(v));
if (ent == attacker)
points = points * 0.5;
if ((points > 0) && CanDamage(ent, inflictor)) //CW
{
//CW++
if (ent->client)
{
if (ent->target_ent && ent->target_ent->client && ent->target_ent->client->spycam)
targ = ent->target_ent; // ...ent -> targ for all below
else
targ = ent;
// Apply freezing effect of Shock Rifle (disintegrator mode) to still-living players.
if (mod == MOD_SR_DISINT_WAVE)
{
if (CheckTeamDamage(targ, attacker))
continue;
if (targ->client->invincible_framenum > level.framenum)
continue;
if ((ent->health > 0) && (targ->client->enviro_framenum <= level.framenum))
{
if (targ == attacker)
gi_centerprintf(targ, "You've frozen yourself\n");
else
//CW++
{
if (!attacker->client)
gi_centerprintf(targ, "You've been frozen\n");
else
//CW--
gi_centerprintf(targ, "You've been frozen by %s\n", attacker->client->pers.netname);
}
if (ent->client->frozen_framenum > level.framenum)
ent->client->frozen_framenum += (int)(10.0 * sv_shock_freeze_time->value); //CW
else
ent->client->frozen_framenum = level.framenum + (int)(10.0 * sv_shock_freeze_time->value); //CW
}
}
// Ignite players who are caught in the blast radius of a firebomb.
else if (mod == MOD_FIREBOMB_SPLASH)
{
if (targ->client->enviro_framenum > level.framenum)
continue;
if (CheckTeamDamage(targ, attacker))
continue;
if (targ->client->invincible_framenum > level.framenum)
continue;
if (!ent->burning)
{
ent->burning = true;
Spawn_Flame(inflictor, ent, ent->s.origin, inflictor->radius_dmg);
}
}
}
VectorSubtract(ent->s.origin, inflictor->s.origin, dir);
T_Damage(ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
}
}
}

3214
awaken2/g_func.c Normal file

File diff suppressed because it is too large Load diff

3571
awaken2/g_items.c Normal file

File diff suppressed because it is too large Load diff

2145
awaken2/g_local.h Normal file

File diff suppressed because it is too large Load diff

1083
awaken2/g_main.c Normal file

File diff suppressed because it is too large Load diff

3690
awaken2/g_menus.c Normal file

File diff suppressed because it is too large Load diff

2041
awaken2/g_misc.c Normal file

File diff suppressed because it is too large Load diff

259
awaken2/g_model.c Normal file
View file

@ -0,0 +1,259 @@
// g_model.c
//CW: This turret code is taken from the Lazarus mod source (version 2.1),
// which David Hyde released on 22-Sep-01 for public use.
// See 'http://planetquake.com/lazarus' for more information.
// ----------------------------------------------------------------------------
//
// mappack stuff by mr. ed, modified extensively for Tremor by dwh
//
//Spawns a user defined model, you can specify whether its solid, if so how big the box is, and apply nearly
//any effect to the entity.
//
// PLAYER set this if you want to use a player model
//
// Note : These flags override any frame settings you may have enterered
// ANIM01 cycle between frames 0 and 1 at 2 hz
// ANIM23 cycle between frames 2 and 3 at 2 hz
// ANIM_ALL cycle through all frames at 2hz
// ANIM_ALLFAST cycle through all frames at 10hz
//
// START_OFF Start inactive, when triggered display the model
// TOGGLE Start active, when triggered become inactive
// NO_MODEL Don't use a model. Usefull for placeing particle effects and
// dynamic lights on their own
//
// "usermodel" = The model to load (models/ is already coded)
// "startframe" = The starting frame : default 0
// "userframes" = The number of frames you want to display after startframe
// "solidstate" = 1 : SOLID_NOT - not solid at all
// 2 : SOLID_BBOX - solid and affected by gravity
// 3 : NO DROP - solid but not affected by gravity
// 4 : SOLID_NOT, but affect by gravity
//
// NOTE : if you want the model to be solid then you must enter vector values into the following fields :
// "bleft" = the point that is at the bottom left of the models bounding box in a model editor
// "tright" = the point that is at the top left of the models bounding box in a model editor
//
#include "g_local.h"
#define TOGGLE 2
#define PLAYER_MODEL 8
#define NO_MODEL 16
#define ANIM_ONCE 32
void model_spawn_use(edict_t *self, edict_t *other, edict_t *activator);
void modelspawn_think (edict_t *self)
{
self->s.frame++;
if (self->s.frame >= self->framenumbers)
{
self->s.frame = self->startframe;
if(self->spawnflags & ANIM_ONCE)
{
model_spawn_use(self,world,world);
return;
}
}
self->nextthink = level.time + FRAMETIME;
gi.linkentity(self);
}
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (self->delay) //we started off
{
self->svflags &= ~SVF_NOCLIENT;
self->delay = 0;
if(self->framenumbers > 1)
{
self->think = modelspawn_think;
self->nextthink = level.time + FRAMETIME;
}
self->s.sound = self->noise_index;
#ifdef LOOP_SOUND_ATTENUATION
self->s.attenuation = self->attenuation;
#endif
}
else //we started active
{
self->svflags |= SVF_NOCLIENT;
self->delay = 1;
self->use = model_spawn_use;
self->think = NULL;
self->nextthink = 0;
self->s.sound = 0;
}
}
void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
/* edict_t *e, *next;
e = self->movewith_next;
while(e) {
next = e->movewith_next;
if(e->solid == SOLID_NOT) {
e->nextthink = 0;
G_FreeEdict(e);
} else
BecomeExplosion1 (e);
e = next;
}
*/
BecomeExplosion1(self);
}
#define ANIM_MASK (EF_ANIM01|EF_ANIM23|EF_ANIM_ALL|EF_ANIM_ALLFAST)
void SP_model_spawn (edict_t *ent)
{
char modelname[256];
//paranoia checks
if ((!ent->usermodel) && !(ent->spawnflags & NO_MODEL) && !(ent->spawnflags & PLAYER_MODEL))
{
gi.dprintf("%s without a model at %s\n", ent->classname, vtos(ent->s.origin));
G_FreeEdict(ent);
return;
}
switch (ent->solidstate)
{
case 1 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
case 2 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_TOSS; break;
case 3 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_NONE; break;
case 4 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_TOSS; break;
default: ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
}
if (ent->solid != SOLID_NOT ) {
if (ent->health > 0) {
ent->die = model_die;
ent->takedamage = DAMAGE_YES;
}
}
switch (ent->style)
{
case 1 : ent->s.effects |= EF_ANIM01; break;
case 2 : ent->s.effects |= EF_ANIM23; break;
case 3 : ent->s.effects |= EF_ANIM_ALL; break;
case 4 : ent->s.effects |= EF_ANIM_ALLFAST; break;
}
// DWH: Rather than use one value (renderfx) we use the
// actual values for effects and renderfx. All may
// be combined.
ent->s.effects |= ent->effects;
ent->s.renderfx |= ent->renderfx;
if (ent->startframe < 0)
ent->startframe = 0;
if (!ent->framenumbers)
ent->framenumbers = 1;
// Change framenumbers to last frame to play
ent->framenumbers += ent->startframe;
if (ent->bleft)
{
VectorCopy (ent->bleft, ent->mins);
}
else
{
if (ent->solid != SOLID_NOT)
{
gi.dprintf("%s solid with no bleft vector at %s\n", ent->classname, vtos(ent->s.origin));
ent->solid = SOLID_NOT;
}
}
if (ent->tright)
{
VectorCopy (ent->tright, ent->maxs);
}
else
{
if (ent->solid != SOLID_NOT)
{
gi.dprintf("%s solid with no tright vector at %s\n", ent->classname, vtos(ent->s.origin));
ent->solid = SOLID_NOT;
}
}
// if (ent->movewith && (ent->solid == SOLID_BBOX))
// if (ent->movewith)
// ent->movetype = MOVETYPE_PUSH;
if (ent->solid != SOLID_NOT)
ent->clipmask = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER;
if (ent->spawnflags & NO_MODEL)
{ // For rendering effects to work, we MUST use a model
ent->s.modelindex = gi.modelindex ("sprites/point.sp2");
ent->movetype = MOVETYPE_NOCLIP;
}
else
{
if (ent->spawnflags & PLAYER_MODEL) {
if (!ent->usermodel || !strlen(ent->usermodel))
ent->s.modelindex = MAX_MODELS-1;
else
{
if (strstr(ent->usermodel,"tris.md2"))
Com_sprintf(modelname, sizeof(modelname), "players/%s", ent->usermodel);
else
Com_sprintf(modelname, sizeof(modelname), "players/%s/tris.md2", ent->usermodel);
ent->s.modelindex = gi.modelindex(modelname);
}
}
else
{
if (strstr(ent->usermodel,".sp2")) {
// Knightmare- check for "sprites/" already in path
if ( !strncmp(ent->usermodel, "sprites/", 8) )
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
else
Com_sprintf(modelname, sizeof(modelname), "sprites/%s", ent->usermodel);
}
else {
// Knightmare- check for "models/" already in path
if ( !strncmp(ent->usermodel, "models/", 7) )
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
else
Com_sprintf(modelname, sizeof(modelname), "models/%s", ent->usermodel);
}
ent->s.modelindex = gi.modelindex (modelname);
}
ent->s.frame = ent->startframe;
}
if (st.noise)
ent->noise_index = gi.soundindex (st.noise);
ent->s.sound = ent->noise_index;
#ifdef LOOP_SOUND_ATTENUATION
ent->s.attenuation = ent->attenuation;
#endif
// if (ent->skinnum) // Knightmare- selectable skin
// ent->s.skinnum = ent->skinnum;
if (ent->spawnflags & ANIM_ONCE)
ent->spawnflags |= TOGGLE;
if (ent->spawnflags & TOGGLE)
{
ent->delay = 0;
ent->use = model_spawn_use;
}
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
{
ent->think = modelspawn_think;
ent->nextthink = level.time + 2*FRAMETIME;
}
gi.linkentity (ent);
}

426
awaken2/g_monster.c Normal file
View file

@ -0,0 +1,426 @@
// g_monster.c
#include "g_local.h"
#define STEPSIZE 18 //CW
/*
===============
M_CheckGround
===============
*/
void M_CheckGround(edict_t *ent)
{
vec3_t point;
trace_t trace;
if (ent->flags & (FL_SWIM|FL_FLY))
return;
//Maj++
ResetGroundSlope(ent);
//Maj--
if (ent->velocity[2] > 100.0)
{
ent->groundentity = NULL;
return;
}
// if the hull point one-quarter unit down is solid the entity is on ground
point[0] = ent->s.origin[0];
point[1] = ent->s.origin[1];
point[2] = ent->s.origin[2] - 0.25;
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, point, ent, MASK_MONSTERSOLID);
// check steepness
if ((trace.plane.normal[2] < 0.7) && !trace.startsolid)
{
ent->groundentity = NULL;
return;
}
/* //Maj - code superseded
if (!trace.startsolid && !trace.allsolid)
{
VectorCopy(trace.endpos, ent->s.origin);
ent->groundentity = trace.ent;
ent->groundentity_linkcount = trace.ent->linkcount;
ent->velocity[2] = 0.0;
}
*/
//Maj++
TraceAllSolid(ent, point, trace);
//Maj--
}
/*
===============
M_CatagorizePosition
===============
*/
void M_CatagorizePosition(edict_t *ent)
{
vec3_t point;
int cont;
// Get the current waterlevel.
point[0] = ent->s.origin[0];
point[1] = ent->s.origin[1];
point[2] = ent->s.origin[2] + ent->mins[2] + 1.0;
cont = gi.pointcontents(point);
if (!(cont & MASK_WATER))
{
ent->waterlevel = 0;
ent->watertype = 0;
return;
}
ent->watertype = cont;
ent->waterlevel = 1;
point[2] += 26.0;
cont = gi.pointcontents(point);
if (!(cont & MASK_WATER))
return;
ent->waterlevel = 2;
point[2] += 22.0;
cont = gi.pointcontents(point);
if (cont & MASK_WATER)
ent->waterlevel = 3;
}
/*
===============
M_DropToFloor
===============
*/
void M_DropToFloor(edict_t *ent)
{
vec3_t end;
trace_t trace;
ent->s.origin[2] += 1.0;
VectorCopy(ent->s.origin, end);
end[2] -= 256.0;
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
if ((trace.fraction == 1.0) || trace.allsolid)
return;
VectorCopy(trace.endpos, ent->s.origin);
gi.linkentity(ent);
M_CheckGround(ent);
M_CatagorizePosition(ent);
}
/*
=============
M_CheckBottom
Returns false if any part of the bottom of the entity is off an edge that
is not a staircase.
=============
*/
qboolean M_CheckBottom(edict_t *ent) //CW
{
vec3_t mins;
vec3_t maxs;
vec3_t start;
vec3_t stop;
trace_t trace;
float mid;
float bottom;
int x;
int y;
VectorAdd(ent->s.origin, ent->mins, mins);
VectorAdd(ent->s.origin, ent->maxs, maxs);
// If all of the points under the corners are solid world, don't bother
// with the tougher checks; the corners must be within 16 units of the midpoint.
start[2] = mins[2] - 1;
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
{
start[0] = (x) ? maxs[0] : mins[0];
start[1] = (y) ? maxs[1] : mins[1];
if (gi.pointcontents(start) != CONTENTS_SOLID)
goto realcheck;
}
}
return true; // we got out easy
realcheck:
// Check it for real...
start[2] = mins[2];
// The midpoint must be within 16 units of the bottom.
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5;
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5;
stop[2] = start[2] - 2 * STEPSIZE;
trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID);
if (trace.fraction == 1.0)
return false;
mid = bottom = trace.endpos[2];
// The corners must be within 16 units of the midpoint.
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
{
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID);
if ((trace.fraction != 1.0) && (trace.endpos[2] > bottom))
bottom = trace.endpos[2];
if ((trace.fraction == 1.0) || (mid - trace.endpos[2] > STEPSIZE))
return false;
}
}
return true;
}
/*
=============
SV_MoveStep
Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
possible, no move is done, false is returned, and
pr_global_struct->trace_normal is set to the normal of the blocking wall
=============
*/
//FIXME since we need to test end position contents here, can we avoid doing
//it again later in catagorize position?
qboolean SV_MoveStep(edict_t *ent, vec3_t move, qboolean relink) //CW
{
trace_t trace;
vec3_t oldorg;
vec3_t neworg;
vec3_t end;
vec3_t test;
float dz;
float stepsize;
int contents;
int i;
// Try the move.
VectorCopy(ent->s.origin, oldorg);
VectorAdd(ent->s.origin, move, neworg);
// Flying monsters don't step up.
if (ent->flags & (FL_SWIM | FL_FLY))
{
// try one move with vertical motion, then one without
for (i = 0; i < 2; i++)
{
VectorAdd(ent->s.origin, move, neworg);
if ((i == 0) && ent->enemy)
{
if (!ent->goalentity)
ent->goalentity = ent->enemy;
dz = ent->s.origin[2] - ent->goalentity->s.origin[2];
if (ent->goalentity->client)
{
if (dz > 40.0)
neworg[2] -= 8.0;
if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
if (dz < 30.0)
neworg[2] += 8.0;
}
else
{
if (dz > 8.0)
neworg[2] -= 8.0;
else if (dz > 0.0)
neworg[2] -= dz;
else if (dz < -8.0)
neworg[2] += 8.0;
else
neworg[2] += dz;
}
}
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID);
// fly monsters don't enter water voluntarily
if (ent->flags & FL_FLY)
{
if (!ent->waterlevel)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
return false;
}
}
// swim monsters don't exit water voluntarily
if (ent->flags & FL_SWIM)
{
if (ent->waterlevel < 2)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
contents = gi.pointcontents(test);
if (!(contents & MASK_WATER))
return false;
}
}
if (trace.fraction == 1.0)
{
VectorCopy(trace.endpos, ent->s.origin);
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
if (!ent->enemy)
break;
}
return false;
}
// Push down from a step height above the wished position.
if (!(ent->monsterinfo.aiflags & AI_NOSTEP))
stepsize = STEPSIZE;
else
stepsize = 1;
neworg[2] += stepsize;
VectorCopy(neworg, end);
end[2] -= stepsize * 2.0;
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
if (trace.allsolid)
return false;
if (trace.startsolid)
{
neworg[2] -= stepsize;
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
if (trace.allsolid || trace.startsolid)
return false;
}
// Don't go into water.
if (ent->waterlevel == 0)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
return false;
}
if (trace.fraction == 1.0)
{
// if monster had the ground pulled out, go ahead and fall
if (ent->flags & FL_PARTIALGROUND)
{
VectorAdd(ent->s.origin, move, ent->s.origin);
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
ent->groundentity = NULL;
return true;
}
return false; // walked off an edge
}
// Check point traces down for dangling corners.
VectorCopy(trace.endpos, ent->s.origin);
if (!M_CheckBottom(ent))
{
if (ent->flags & FL_PARTIALGROUND)
{ // entity had floor mostly pulled out from underneath it and is trying to correct
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
VectorCopy(oldorg, ent->s.origin);
return false;
}
if (ent->flags & FL_PARTIALGROUND)
ent->flags &= ~FL_PARTIALGROUND;
ent->groundentity = trace.ent;
ent->groundentity_linkcount = trace.ent->linkcount;
// The move is OK.
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
/*
===============
M_WalkMove
===============
*/
qboolean M_WalkMove(edict_t *ent, float yaw, float dist) //CW
{
vec3_t move;
if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
return false;
yaw = DEG2RAD(yaw); //CW
move[0] = cos(yaw) * dist;
move[1] = sin(yaw) * dist;
move[2] = 0.0;
return SV_MoveStep(ent, move, true);
}

165
awaken2/g_mtrain.c Normal file
View file

@ -0,0 +1,165 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
Copyright (C) 2000-2002 Mr. Hyde and Mad Dog
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "g_local.h"
void func_train_find (edict_t *self);
void SP_model_spawn (edict_t *ent);
void train_blocked (edict_t *self, edict_t *other);
void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
void train_use (edict_t *self, edict_t *other, edict_t *activator);
#define TRAIN_START_ON 1
#define TRAIN_TOGGLE 2
#define TRAIN_BLOCK_STOPS 4
#define PLAYER_MODEL 8
#define NO_MODEL 16
#define MTRAIN_ROTATE 32
#define MTRAIN_ROTATE_CONSTANT 64
#define TRAIN_SMOOTH 128
void model_train_animator(edict_t *animator)
{
edict_t *train;
train = animator->owner;
if (!train || !train->inuse)
{
G_FreeEdict(animator);
return;
}
if (Q_stricmp(train->classname,"model_train"))
{
G_FreeEdict(animator);
return;
}
animator->nextthink = level.time + FRAMETIME;
if (VectorLength(train->velocity) == 0)
return;
train->s.frame++;
if (train->s.frame >= train->framenumbers)
train->s.frame = train->startframe;
gi.linkentity(train);
}
void SP_model_train (edict_t *self)
{
SP_model_spawn (self);
// self->class_id = ENTITY_MODEL_TRAIN;
// Reset s.sound, which SP_model_spawn may have turned on
self->moveinfo.sound_middle = self->s.sound;
self->s.sound = 0;
if (!self->inuse) return;
// Reset some things from SP_model_spawn
self->delay = 0;
self->think = NULL;
self->nextthink = 0;
if (self->health)
{
self->die = train_die;
self->takedamage = DAMAGE_YES;
}
if (self->framenumbers > self->startframe+1)
{
edict_t *animator;
animator = G_Spawn();
animator->owner = self;
animator->think = model_train_animator;
animator->nextthink = level.time + FRAMETIME;
}
self->s.frame = self->startframe;
self->movetype = MOVETYPE_PUSH;
// Really gross stuff here... translate model_spawn spawnflags
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
// already been checked in SP_model_spawn and are never re-used,
// so it's OK to overwrite those.
if (self->spawnflags & MTRAIN_ROTATE)
{
self->spawnflags &= ~MTRAIN_ROTATE;
self->spawnflags |= TRAIN_ROTATE;
}
if (self->spawnflags & MTRAIN_ROTATE_CONSTANT)
{
self->spawnflags &= ~MTRAIN_ROTATE_CONSTANT;
self->spawnflags |= TRAIN_ROTATE_CONSTANT;
}
if ( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
{
self->spawnflags &= ~(TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT);
self->spawnflags |= TRAIN_SPLINE;
}
if (self->style == 3)
self->spawnflags |= TRAIN_ANIMATE; // 32
if (self->style == 4)
self->spawnflags |= TRAIN_ANIMATE_FAST; // 64
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
// Move_Final rather than slowing down (if necessary) for one
// frame.
if (self->spawnflags & TRAIN_SMOOTH)
self->smooth_movement = true;
else
self->smooth_movement = false;
self->blocked = train_blocked;
if (self->spawnflags & TRAIN_BLOCK_STOPS)
self->dmg = 0;
else
{
if (!self->dmg)
self->dmg = 100;
}
if (!self->speed)
self->speed = 100;
self->moveinfo.speed = self->speed;
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
self->use = train_use;
gi.linkentity (self);
if (self->target)
{
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
self->nextthink = level.time + FRAMETIME;
self->think = func_train_find;
}
else
{
gi.dprintf ("model_train without a target at %s\n", vtos(self->absmin));
}
}
void SP_model_train_origin (edict_t *self)
{
self->spawnflags |= TRAIN_ORIGIN;
SP_model_train (self);
}

347
awaken2/g_newfnc.c Normal file
View file

@ -0,0 +1,347 @@
#include "g_local.h"
//void plat_CalcMove (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
void fd_secret_move1(edict_t *self);
void fd_secret_move2(edict_t *self);
void fd_secret_move3(edict_t *self);
void fd_secret_move4(edict_t *self);
void fd_secret_move5(edict_t *self);
void fd_secret_move6(edict_t *self);
void fd_secret_done(edict_t *self);
/*
=============================================================================
SECRET DOORS
=============================================================================
*/
#define SEC_OPEN_ONCE 1 // stays open
#define SEC_1ST_LEFT 2 // 1st move is left of arrow
#define SEC_1ST_DOWN 4 // 1st move is down from arrow
#define SEC_NO_SHOOT 8 // only opened by trigger
#define SEC_YES_SHOOT 16 // shootable even if targeted
#define SEC_MOVE_RIGHT 32
#define SEC_MOVE_FORWARD 64
void fd_secret_use (edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *ent;
// gi.dprintf("fd_secret_use\n");
if (self->flags & FL_TEAMSLAVE)
return;
// trigger all paired doors
for (ent = self ; ent ; ent = ent->teamchain)
Move_Calc(ent, ent->moveinfo.start_origin, fd_secret_move1);
}
void fd_secret_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
// gi.dprintf("fd_secret_killed\n");
self->health = self->max_health;
self->takedamage = DAMAGE_NO;
if (self->flags & FL_TEAMSLAVE && self->teammaster && self->teammaster->takedamage != DAMAGE_NO)
fd_secret_killed (self->teammaster, inflictor, attacker, damage, point);
else
fd_secret_use (self, inflictor, attacker);
}
// Wait after first movement...
void fd_secret_move1(edict_t *self)
{
// gi.dprintf("fd_secret_move1\n");
self->nextthink = level.time + 1.0;
self->think = fd_secret_move2;
}
// Start moving sideways w/sound...
void fd_secret_move2(edict_t *self)
{
// gi.dprintf("fd_secret_move2\n");
Move_Calc(self, self->moveinfo.end_origin, fd_secret_move3);
}
// Wait here until time to go back...
void fd_secret_move3(edict_t *self)
{
// gi.dprintf("fd_secret_move3\n");
if (!(self->spawnflags & SEC_OPEN_ONCE))
{
self->nextthink = level.time + self->wait;
self->think = fd_secret_move4;
}
}
// Move backward...
void fd_secret_move4(edict_t *self)
{
// gi.dprintf("fd_secret_move4\n");
Move_Calc(self, self->moveinfo.start_origin, fd_secret_move5);
}
// Wait 1 second...
void fd_secret_move5(edict_t *self)
{
// gi.dprintf("fd_secret_move5\n");
self->nextthink = level.time + 1.0;
self->think = fd_secret_move6;
}
void fd_secret_move6(edict_t *self)
{
// gi.dprintf("fd_secret_move6\n");
Move_Calc(self, self->move_origin, fd_secret_done);
}
void fd_secret_done(edict_t *self)
{
// gi.dprintf("fd_secret_done\n");
if (!self->targetname || self->spawnflags & SEC_YES_SHOOT)
{
self->health = 1;
self->takedamage = DAMAGE_YES;
self->die = fd_secret_killed;
}
}
void secret_blocked(edict_t *self, edict_t *other)
{
if (!(self->flags & FL_TEAMSLAVE))
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 0, 0, MOD_CRUSH);
// if (time < self->attack_finished)
// return;
// self->attack_finished = time + 0.5;
// T_Damage (other, self, self, self->dmg);
}
/*
================
secret_touch
Prints messages
================
*/
void secret_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other->health <= 0)
return;
if (!(other->client))
return;
if (self->monsterinfo.attack_finished > level.time)
return;
self->monsterinfo.attack_finished = level.time + 2;
if (self->message)
{
gi.centerprintf (other, self->message);
// fixme - put this sound back??
// gi.sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
}
/*QUAKED func_door_secret2 (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot slide_right slide_forward
Basic secret door. Slides back, then to the left. Angle determines direction.
FLAGS:
open_once = not implemented yet
1st_left = 1st move is left/right of arrow
1st_down = 1st move is forwards/backwards
no_shoot = not implemented yet
always_shoot = even if targeted, keep shootable
reverse_left = the sideways move will be to right of arrow
reverse_back = the to/fro move will be forward
VALUES:
wait = # of seconds before coming back (5 default)
dmg = damage to inflict when blocked (2 default)
*/
void SP_func_door_secret2 (edict_t *ent)
{
vec3_t forward,right,up;
float lrSize, fbSize;
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
if (!ent->dmg)
ent->dmg = 2;
AngleVectors(ent->s.angles, forward, right, up);
VectorCopy(ent->s.origin, ent->move_origin);
VectorCopy(ent->s.angles, ent->move_angles);
G_SetMovedir (ent->s.angles, ent->movedir);
ent->movetype = MOVETYPE_PUSH;
ent->solid = SOLID_BSP;
gi.setmodel (ent, ent->model);
if(ent->move_angles[1] == 0 || ent->move_angles[1] == 180)
{
lrSize = ent->size[1];
fbSize = ent->size[0];
}
else if(ent->move_angles[1] == 90 || ent->move_angles[1] == 270)
{
lrSize = ent->size[0];
fbSize = ent->size[1];
}
else
{
gi.dprintf("Secret door not at 0,90,180,270!\n");
}
if(ent->spawnflags & SEC_MOVE_FORWARD)
VectorScale(forward, fbSize, forward);
else
{
VectorScale(forward, fbSize * -1 , forward);
}
if(ent->spawnflags & SEC_MOVE_RIGHT)
VectorScale(right, lrSize, right);
else
{
VectorScale(right, lrSize * -1, right);
}
if(ent->spawnflags & SEC_1ST_DOWN)
{
VectorAdd(ent->s.origin, forward, ent->moveinfo.start_origin);
VectorAdd(ent->moveinfo.start_origin, right, ent->moveinfo.end_origin);
}
else
{
VectorAdd(ent->s.origin, right, ent->moveinfo.start_origin);
VectorAdd(ent->moveinfo.start_origin, forward, ent->moveinfo.end_origin);
}
ent->touch = secret_touch;
ent->blocked = secret_blocked;
ent->use = fd_secret_use;
ent->moveinfo.speed = 50;
ent->moveinfo.accel = 50;
ent->moveinfo.decel = 50;
if (!ent->targetname || ent->spawnflags & SEC_YES_SHOOT)
{
ent->health = 1;
ent->max_health = ent->health;
ent->takedamage = DAMAGE_YES;
ent->die = fd_secret_killed;
}
if (!ent->wait)
ent->wait = 5; // 5 seconds before closing
gi.linkentity(ent);
}
// ==================================================
#define FWALL_START_ON 1
void force_wall_think(edict_t *self)
{
if(!self->wait)
{
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_FORCEWALL);
gi.WritePosition (self->pos1);
gi.WritePosition (self->pos2);
gi.WriteByte (self->style);
gi.multicast (self->offset, MULTICAST_PVS);
}
self->think = force_wall_think;
self->nextthink = level.time + 0.1;
}
void force_wall_use (edict_t *self, edict_t *other, edict_t *activator)
{
if(!self->wait)
{
self->wait = 1;
self->think = NULL;
self->nextthink = 0;
self->solid = SOLID_NOT;
gi.linkentity( self );
}
else
{
self->wait = 0;
self->think = force_wall_think;
self->nextthink = level.time + 0.1;
self->solid = SOLID_BSP;
KillBox(self); // Is this appropriate?
gi.linkentity (self);
}
}
/*QUAKED func_force_wall (1 0 1) ? start_on
A vertical particle force wall. Turns on and solid when triggered.
If someone is in the force wall when it turns on, they're telefragged.
start_on - forcewall begins activated. triggering will turn it off.
style - color of particles to use.
208: green, 240: red, 241: blue, 224: orange
*/
void SP_func_force_wall(edict_t *ent)
{
gi.setmodel (ent, ent->model);
ent->offset[0] = (ent->absmax[0] + ent->absmin[0]) / 2;
ent->offset[1] = (ent->absmax[1] + ent->absmin[1]) / 2;
ent->offset[2] = (ent->absmax[2] + ent->absmin[2]) / 2;
ent->pos1[2] = ent->absmax[2];
ent->pos2[2] = ent->absmax[2];
if(ent->size[0] > ent->size[1])
{
ent->pos1[0] = ent->absmin[0];
ent->pos2[0] = ent->absmax[0];
ent->pos1[1] = ent->offset[1];
ent->pos2[1] = ent->offset[1];
}
else
{
ent->pos1[0] = ent->offset[0];
ent->pos2[0] = ent->offset[0];
ent->pos1[1] = ent->absmin[1];
ent->pos2[1] = ent->absmax[1];
}
if(!ent->style)
ent->style = 208;
ent->movetype = MOVETYPE_NONE;
ent->wait = 1;
if(ent->spawnflags & FWALL_START_ON)
{
ent->solid = SOLID_BSP;
ent->think = force_wall_think;
ent->nextthink = level.time + 0.1;
}
else
ent->solid = SOLID_NOT;
ent->use = force_wall_use;
ent->svflags = SVF_NOCLIENT;
gi.linkentity(ent);
}

1425
awaken2/g_phys.c Normal file

File diff suppressed because it is too large Load diff

1262
awaken2/g_save.c Normal file

File diff suppressed because it is too large Load diff

1455
awaken2/g_spawn.c Normal file

File diff suppressed because it is too large Load diff

586
awaken2/g_svcmds.c Normal file
View file

@ -0,0 +1,586 @@
// g_svcmds.c
#include "g_local.h"
void SVCmd_Test_f(void)
{
gi.cprintf(NULL, PRINT_HIGH, "SVCmd_Test_f()\n");
}
/*
==============================================================================
PACKET FILTERING
You can add or remove addresses from the filter list with:
addip <ip>
removeip <ip>
The ip address is specified in dot format, and any unspecified digits will match any value,
so you can specify an entire class C network with "addip 192.246.40".
Removeip will only remove an address specified exactly the same way. You cannot addip a
subnet, then removeip a single host.
listip
Prints the current list of filters.
writeip
Dumps "addip <ip>" commands to listip.cfg so it can be execed at a later date. The filter
lists are not saved and restored by default, because I believe it would cause too much confusion.
filterban <0 or 1>
If 1 (the default), then ip addresses matching the current list will be prohibited from entering
the game (this is the default setting).
If 0, then only addresses matching the list will be allowed. This lets you easily set up a
private game, or a game that only allows players from your local network.
==============================================================================
*/
typedef struct
{
unsigned mask;
unsigned compare;
} ipfilter_t;
#define MAX_IPFILTERS 1024
ipfilter_t ipfilters[MAX_IPFILTERS];
int numipfilters;
/*
=================
StringToFilter
=================
*/
static qboolean StringToFilter(char *s, ipfilter_t *f)
{
char num[128];
int i;
int j;
byte b[4];
byte m[4];
for (i = 0; i < 4; i++)
{
b[i] = 0;
m[i] = 0;
}
for (i = 0; i < 4; i++)
{
if ((*s < '0') || (*s > '9'))
{
gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
return false;
}
j = 0;
while ((*s >= '0') && (*s <= '9'))
{
num[j++] = *s++;
}
num[j] = 0;
b[i] = atoi(num);
if (b[i] != 0)
m[i] = 255;
if (!*s)
break;
s++;
}
f->mask = *(unsigned *)m;
f->compare = *(unsigned *)b;
return true;
}
/*
=================
SV_FilterPacket
=================
*/
qboolean SV_FilterPacket(char *from)
{
char *p;
byte m[4];
int i;
unsigned in;
i = 0;
p = from;
while (*p && (i < 4))
{
m[i] = 0;
while ((*p >= '0') && (*p <= '9'))
{
m[i] = (m[i] * 10) + (*p - '0');
p++;
}
if (!*p || (*p == ':'))
break;
i++, p++;
}
in = *(unsigned *)m;
for (i = 0; i < numipfilters; i++)
{
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
return (int)filterban->value;
}
return (int)!filterban->value;
}
/*
=================
SVCmd_AddIP_f
=================
*/
void SVCmd_AddIP_f(void)
{
int i;
if (gi.argc() < 3)
{
gi.cprintf(NULL, PRINT_HIGH, "Usage: addip <ip-mask>\n");
return;
}
for (i = 0; i < numipfilters; i++)
{
if (ipfilters[i].compare == 0xffffffff)
break; // free spot
}
if (i == numipfilters)
{
if (numipfilters == MAX_IPFILTERS)
{
gi.cprintf(NULL, PRINT_HIGH, "IP filter list is full\n");
return;
}
numipfilters++;
}
if (!StringToFilter(gi.argv(2), &ipfilters[i]))
ipfilters[i].compare = 0xffffffff;
}
/*
=================
SVCmd_RemoveIP_f
=================
*/
void SVCmd_RemoveIP_f(void)
{
ipfilter_t f;
int i;
int j;
if (gi.argc() < 3)
{
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv removeip <ip-mask>\n");
return;
}
if (!StringToFilter(gi.argv(2), &f))
return;
for (i = 0; i < numipfilters; i++)
{
if ((ipfilters[i].mask == f.mask) && (ipfilters[i].compare == f.compare))
{
for (j = i+1; j < numipfilters; j++)
ipfilters[j-1] = ipfilters[j];
numipfilters--;
gi.cprintf(NULL, PRINT_HIGH, "Removed.\n");
return;
}
}
gi.cprintf(NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
}
/*
=================
SVCmd_ListIP_f
=================
*/
void SVCmd_ListIP_f(void)
{
int i;
byte b[4];
gi.cprintf(NULL, PRINT_HIGH, "Filter list:\n");
for (i = 0; i < numipfilters; i++)
{
*(unsigned *)b = ipfilters[i].compare;
gi.cprintf(NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
}
}
/*
=================
SVCmd_WriteIP_f
=================
*/
void SVCmd_WriteIP_f(void)
{
FILE *f;
cvar_t *game;
char name[MAX_OSPATH];
byte b[4];
int i;
game = gi.cvar("game", "", 0);
if (!*game->string)
Com_sprintf(name, sizeof(name), "%s/listip.cfg", GAMEVERSION);
else
Com_sprintf(name, sizeof(name), "%s/listip.cfg", game->string);
gi.cprintf(NULL, PRINT_HIGH, "Writing %s.\n", name);
f = fopen(name, "wb");
if (!f)
{
gi.cprintf(NULL, PRINT_HIGH, "Couldn't open %s\n", name);
return;
}
fprintf(f, "set filterban %d\n", (int)filterban->value);
for (i = 0; i < numipfilters; i++)
{
*(unsigned *)b = ipfilters[i].compare;
fprintf(f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
}
fclose(f);
}
//CW++
/*
=================
SVCmd_AddOP_f
=================
*/
void SVCmd_AddOP_f(void)
{
edict_t *targ;
int i = 0;
if (gi.argc() < 3)
{
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv add_op <player_num>\n");
return;
}
i = atoi(gi.argv(2));
if ((i < 1) || (i > (int)maxclients->value))
{
gi.cprintf(NULL, PRINT_HIGH, "Invalid player number.\n");
return;
}
targ = g_edicts + i;
if (!targ->inuse)
{
gi.cprintf(NULL, PRINT_HIGH, "That player number is not connected.\n");
return;
}
if (targ->client->pers.op_status)
{
gi.cprintf(NULL, PRINT_HIGH, "That player already has OP status.\n");
return;
}
targ->client->pers.op_status = true;
gi_bprintf(PRINT_CHAT, "OP status given to %s.\n", targ->client->pers.netname);
}
/*
=================
SVCmd_DelOP_f
=================
*/
void SVCmd_DelOP_f(void)
{
edict_t *targ;
int i = 0;
if (gi.argc() < 3)
{
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv del_op <player_num>\n");
return;
}
i = atoi(gi.argv(2));
if ((i < 1) || (i > (int)maxclients->value))
{
gi.cprintf(NULL, PRINT_HIGH, "Invalid player number.\n");
return;
}
targ = g_edicts + i;
if (!targ->inuse)
{
gi.cprintf(NULL, PRINT_HIGH, "That player number is not connected.\n");
return;
}
if (!targ->client->pers.op_status)
{
gi.cprintf(NULL, PRINT_HIGH, "That player already lacks OP status.\n");
return;
}
targ->client->pers.op_status = false;
gi_bprintf(PRINT_CHAT, "OP status removed from %s.\n", targ->client->pers.netname);
}
/*
==================
SVCmd_DevEdicts_f
==================
*/
void SVCmd_DevEdicts_f(void)
{
edict_t *ent;
int i;
ent = &g_edicts[0];
for (i = 0; i < globals.num_edicts ; ++i, ++ent)
gi.dprintf("%4d %-24.24s %s %s\n", i, ent->classname, (ent->inuse)?"T":".", vtosf(ent->s.origin));
}
/*
=================
SVCmd_AddBots_f
=================
*/
void SVCmd_AddBots_f(void)
{
edict_t *remover = NULL;
int i = 0;
if (gi.argc() < 3)
{
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv addbots <number>\n");
return;
}
if (!(int)sv_allow_bots->value)
{
gi.cprintf(NULL, PRINT_HIGH, "AwakenBots are not enabled on this server.\n");
return;
}
if (((int)sv_gametype->value == G_CTF) || ((int)sv_gametype->value == G_ASLT))
{
gi.cprintf(NULL, PRINT_HIGH, "AwakenBots are not available for this gametype.\n");
return;
}
if ((int)chedit->value)
{
gi.cprintf(NULL, PRINT_HIGH, "Can't add bots during route creation.");
return;
}
if (teamgame.match > MATCH_SETUP)
{
gi.cprintf(NULL, PRINT_HIGH, "Cannot add bots during a match.\n");
return;
}
if ((remover = G_Find(NULL, FOFS(classname), "bot_remover")) != NULL)
{
gi.cprintf(NULL, PRINT_HIGH, "Cannot add bots - some are still being removed.\n");
return;
}
i = atoi(gi.argv(2));
if (i < 1)
{
gi.cprintf(NULL, PRINT_HIGH, "Invalid number of bots.\n");
return;
}
SpawnNumBots_Safe(i);
}
/*
=================
SVCmd_ClearBots_f
=================
*/
void SVCmd_ClearBots_f(void)
{
edict_t *spawner = NULL;
if (!(int)sv_allow_bots->value)
return;
if ((int)chedit->value)
return;
if (((int)sv_gametype->value == G_CTF) || ((int)sv_gametype->value == G_ASLT))
return;
if (teamgame.match > MATCH_SETUP)
{
gi.cprintf(NULL, PRINT_HIGH, "Cannot remove bots during a match.\n");
return;
}
if ((spawner = G_Find(NULL, FOFS(classname), "bot_spawner")) != NULL)
{
gi.cprintf(NULL, PRINT_HIGH, "Cannot clear bots - some are still being added.\n");
return;
}
if (gi.argc() < 3)
RemoveNumBots_Safe(MAXBOTS);
else
RemoveNumBots_Safe(atoi(gi.argv(2)));
}
/*
=================
SVCmd_ListBots_f
=================
*/
void SVCmd_ListBots_f(void)
{
edict_t *ent;
int i;
for (i = 1; i <= (int)maxclients->value; i++)
{
ent = g_edicts + i;
if (!ent->inuse)
continue;
if (!ent->isabot)
continue;
gi.dprintf("%3d %-16.16s %03d [%d:%d:%d]\n", i,
ent->client->pers.netname,
ent->client->resp.score,
Bot[ent->client->pers.botindex].skill[AIMACCURACY],
Bot[ent->client->pers.botindex].skill[AGGRESSION],
Bot[ent->client->pers.botindex].skill[COMBATSKILL]);
}
}
//CW--
//Pon++
/*
=================
SVCmd_SaveChain_f
=================
*/
void SVCmd_SaveChain_f(void)
{
unsigned int size;
char name[256];
FILE *fpout;
//CW++
cvar_t *game;
//CW--
if (!(int)chedit->value)
{
gi.cprintf(NULL, PRINT_HIGH, "Not in chaining mode!\n");
return;
}
//CW++
game = gi.cvar("game", "", 0);
if (!*game->string)
Com_sprintf(name, sizeof(name), "%s/botroutes/%s.chn", GAMEVERSION, level.mapname);
else
Com_sprintf(name, sizeof(name), "%s/botroutes/%s.chn", game->string, level.mapname);
//CW--
fpout = fopen(name, "wb");
if (fpout == NULL)
gi.cprintf(NULL, PRINT_HIGH, "Can't open %s\n", name);
else
{
fwrite("3ZBRGDTM", sizeof(char), 8, fpout);
fwrite(&CurrentIndex, sizeof(int), 1, fpout);
size = (unsigned int)CurrentIndex * sizeof(route_t);
fwrite(Route, size, 1, fpout);
gi.cprintf(NULL, PRINT_HIGH, "Route data saved to: %s\n", name);
fclose(fpout);
}
}
//Pon--
/*
=================
ServerCommand
ServerCommand will be called when an "sv" command is issued.
The game can issue gi.argc() / gi.argv() commands to get the rest
of the parameters
=================
*/
void ServerCommand(void)
{
char *cmd;
cmd = gi.argv(1);
if (Q_stricmp(cmd, "test") == 0)
SVCmd_Test_f();
else if (Q_stricmp(cmd, "addip") == 0)
SVCmd_AddIP_f();
else if (Q_stricmp(cmd, "removeip") == 0)
SVCmd_RemoveIP_f();
else if (Q_stricmp(cmd, "listip") == 0)
SVCmd_ListIP_f();
else if (Q_stricmp(cmd, "writeip") == 0)
SVCmd_WriteIP_f();
//CW++
else if (!Q_stricmp(cmd, "add_op"))
SVCmd_AddOP_f();
else if (!Q_stricmp(cmd, "del_op"))
SVCmd_DelOP_f();
else if (!Q_stricmp(cmd, "dev_edicts"))
SVCmd_DevEdicts_f();
else if (!Q_stricmp(cmd, "addbots"))
SVCmd_AddBots_f();
else if (!Q_stricmp(cmd, "clearbots"))
SVCmd_ClearBots_f();
else if (!Q_stricmp(cmd, "listbots"))
SVCmd_ListBots_f();
//CW--
//Pon++
else if (!Q_stricmp(cmd, "savechain"))
SVCmd_SaveChain_f();
//Pon--
else
gi.cprintf(NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
}

577
awaken2/g_target.c Normal file
View file

@ -0,0 +1,577 @@
// g_target.c
#include "g_local.h"
/*QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8)
Fire an origin based temp entity event to the clients.
"style" type byte
*/
void Use_Target_Tent(edict_t *ent, edict_t *other, edict_t *activator)
{
gi.WriteByte(svc_temp_entity);
gi.WriteByte(ent->style);
gi.WritePosition(ent->s.origin);
gi.multicast(ent->s.origin, MULTICAST_PVS);
}
void SP_target_temp_entity(edict_t *ent)
{
ent->use = Use_Target_Tent;
//CW++
ent->svflags |= SVF_NOCLIENT;
//CW--
}
//==========================================================
/*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off reliable
"noise" wav file to play
"attenuation"
-1 = none, send to whole level
1 = normal fighting sounds
2 = idle sound level
3 = ambient sound level
"volume" 0.0 to 1.0
Normal sounds play each time the target is used. The reliable flag can be set for crucial voiceovers.
Looped sounds are allways atten 3 / vol 1, and the use function toggles it on/off.
Multiple identical looping sounds will just increase volume without any speed cost.
*/
void Use_Target_Speaker(edict_t *ent, edict_t *other, edict_t *activator)
{
int chan;
if (ent->spawnflags & 3)
{ // looping sound toggles
if (ent->s.sound)
ent->s.sound = 0; // turn it off
else
ent->s.sound = ent->noise_index; // start it
}
else
{ // normal sound
if (ent->spawnflags & 4)
chan = CHAN_VOICE | CHAN_RELIABLE;
else
chan = CHAN_VOICE;
// use a positioned_sound, because this entity won't normally be
// sent to any clients because it is invisible
gi.positioned_sound(ent->s.origin, ent, chan, ent->noise_index, ent->volume, ent->attenuation, 0);
}
}
void SP_target_speaker(edict_t *ent)
{
char buffer[MAX_QPATH];
if (!st.noise)
{
gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin));
return;
}
if (!strstr (st.noise, ".wav"))
Com_sprintf(buffer, sizeof(buffer), "%s.wav", st.noise);
else
strncpy(buffer, st.noise, sizeof(buffer));
ent->noise_index = gi.soundindex (buffer);
if (!ent->volume)
ent->volume = 1.0;
if (!ent->attenuation)
ent->attenuation = 1.0;
else if (ent->attenuation == -1) // use -1 so 0 defaults to 1
ent->attenuation = 0;
// check for prestarted looping sound
if (ent->spawnflags & 1)
ent->s.sound = ent->noise_index;
ent->use = Use_Target_Speaker;
// must link the entity so we get areas and clusters so
// the server can determine who to send updates to
gi.linkentity(ent);
}
//==========================================================
/*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8)
Spawns an explosion temporary entity when used.
"delay" wait this long before going off
"dmg" how much radius damage should be done, defaults to 0
*/
void target_explosion_explode(edict_t *self)
{
float save;
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_EXPLOSION1);
gi.WritePosition(self->s.origin);
gi.multicast(self->s.origin, MULTICAST_PHS);
T_RadiusDamage(self, self->activator, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE);
save = self->delay;
self->delay = 0.0;
G_UseTargets(self, self->activator);
self->delay = save;
}
void use_target_explosion(edict_t *self, edict_t *other, edict_t *activator)
{
self->activator = activator;
if (!self->delay)
{
target_explosion_explode(self);
return;
}
self->think = target_explosion_explode;
self->nextthink = level.time + self->delay;
}
void SP_target_explosion(edict_t *ent)
{
ent->use = use_target_explosion;
ent->svflags = SVF_NOCLIENT;
}
//==========================================================
/*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8)
Changes level to "map" when fired
*/
void use_target_changelevel(edict_t *self, edict_t *other, edict_t *activator)
{
// ignore if already activated
if (level.intermissiontime)
return;
// if noexit, do a ton of damage to other
if (!((int)dmflags->value & DF_ALLOW_EXIT) && (other != world)) //CW
{
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT);
return;
}
// let everyone know who hit the exit
if (activator && activator->client) //CW
gi_bprintf (PRINT_HIGH, "%s exited the level.\n", activator->client->pers.netname);
// if going to a new unit, clear cross triggers
if (strstr(self->map, "*"))
game.serverflags &= ~(SFL_CROSS_TRIGGER_MASK);
BeginIntermission(self);
}
void SP_target_changelevel(edict_t *ent)
{
if (!ent->map)
{
gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin));
G_FreeEdict(ent);
return;
}
// ugly hack because *SOMEBODY* screwed up their map
if((Q_stricmp(level.mapname, "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0))
ent->map = "fact3$secret1";
ent->use = use_target_changelevel;
ent->svflags = SVF_NOCLIENT;
}
//==========================================================
/*QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8)
Creates a particle splash effect when used.
Set "sounds" to one of the following:
1) sparks
2) blue water
3) brown water
4) slime
5) lava
6) blood
"count" how many pixels in the splash
"dmg" if set, does a radius damage at this location when it splashes
useful for lava/sparks
*/
void use_target_splash(edict_t *self, edict_t *other, edict_t *activator)
{
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_SPLASH);
gi.WriteByte(self->count);
gi.WritePosition(self->s.origin);
gi.WriteDir(self->movedir);
gi.WriteByte(self->sounds);
gi.multicast(self->s.origin, MULTICAST_PVS);
if (self->dmg)
T_RadiusDamage(self, activator, self->dmg, NULL, self->dmg+40, MOD_SPLASH);
}
void SP_target_splash(edict_t *self)
{
self->use = use_target_splash;
G_SetMovedir(self->s.angles, self->movedir);
if (!self->count)
self->count = 32;
self->svflags = SVF_NOCLIENT;
}
//==========================================================
/*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8)
Set target to the type of entity you want spawned.
Useful for spawning monsters and gibs in the factory levels.
For monsters:
Set direction to the facing you want it to have.
For gibs:
Set direction if you want it moving and
speed how fast it should be moving otherwise it
will just be dropped
*/
void ED_CallSpawn(edict_t *ent);
void use_target_spawner(edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *ent;
ent = G_Spawn();
ent->classname = self->target;
VectorCopy(self->s.origin, ent->s.origin);
VectorCopy(self->s.angles, ent->s.angles);
ED_CallSpawn(ent);
gi.unlinkentity(ent);
KillBox(ent);
gi.linkentity(ent);
if (self->speed)
VectorCopy(self->movedir, ent->velocity);
}
void SP_target_spawner(edict_t *self)
{
self->use = use_target_spawner;
self->svflags = SVF_NOCLIENT;
if (self->speed)
{
G_SetMovedir(self->s.angles, self->movedir);
VectorScale(self->movedir, self->speed, self->movedir);
}
}
//==========================================================
/*QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTS
Fires a blaster bolt in the set direction when triggered.
dmg default is 15
speed default is 1000
*/
void use_target_blaster(edict_t *self, edict_t *other, edict_t *activator)
{
int effect;
if (self->spawnflags & 2)
effect = 0;
else if (self->spawnflags & 1)
effect = EF_HYPERBLASTER;
else
effect = EF_BLASTER;
Fire_Blaster(self, self->s.origin, self->movedir, self->dmg, self->speed, effect); //CW
gi.sound(self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0);
}
void SP_target_blaster(edict_t *self)
{
self->use = use_target_blaster;
G_SetMovedir(self->s.angles, self->movedir);
self->noise_index = gi.soundindex("weapons/laser2.wav");
if (!self->dmg)
self->dmg = 15;
if (!self->speed)
self->speed = 1000.0;
self->svflags = SVF_NOCLIENT;
}
//==========================================================
/*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT
When triggered, fires a laser. You can either set a target
or a direction.
*/
void target_laser_think(edict_t *self)
{
edict_t *ignore;
trace_t tr;
vec3_t start;
vec3_t end;
vec3_t point;
vec3_t last_movedir;
int count;
if (self->spawnflags & 0x80000000)
count = 8;
else
count = 4;
if (self->enemy)
{
VectorCopy(self->movedir, last_movedir);
VectorMA(self->enemy->absmin, 0.5, self->enemy->size, point);
VectorSubtract(point, self->s.origin, self->movedir);
VectorNormalize(self->movedir);
if (!VectorCompare(self->movedir, last_movedir))
self->spawnflags |= 0x80000000;
}
ignore = self;
VectorCopy(self->s.origin, start);
VectorMA(start, 2048.0, self->movedir, end);
while (1)
{
tr = gi.trace(start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);
if (!tr.ent)
break;
// hurt it if we can
if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER))
//CW++
{
if (tr.ent->client && (tr.ent->client->agm_enemy != NULL))
T_Damage(tr.ent, self, tr.ent->client->agm_enemy, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_AGM_TARG_LASER);
else
//CW--
T_Damage(tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);
}
// if we hit something that's not a monster or player or is immune to lasers, we're done
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
{
if (self->spawnflags & 0x80000000)
{
self->spawnflags &= ~0x80000000;
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_LASER_SPARKS);
gi.WriteByte(count);
gi.WritePosition(tr.endpos);
gi.WriteDir(tr.plane.normal);
gi.WriteByte(self->s.skinnum);
gi.multicast(tr.endpos, MULTICAST_PVS);
}
break;
}
ignore = tr.ent;
VectorCopy(tr.endpos, start);
}
VectorCopy(tr.endpos, self->s.old_origin);
self->nextthink = level.time + FRAMETIME;
}
void target_laser_on(edict_t *self)
{
if (!self->activator)
self->activator = self;
self->spawnflags |= 0x80000001;
self->svflags &= ~SVF_NOCLIENT;
target_laser_think(self);
}
void target_laser_off(edict_t *self)
{
self->spawnflags &= ~1;
self->svflags |= SVF_NOCLIENT;
self->nextthink = 0.0;
}
void target_laser_use(edict_t *self, edict_t *other, edict_t *activator)
{
self->activator = activator;
if (self->spawnflags & 1)
target_laser_off (self);
else
target_laser_on (self);
}
void target_laser_start(edict_t *self)
{
edict_t *ent;
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
self->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
self->s.modelindex = 1; // must be non-zero
// set the beam diameter
if (self->spawnflags & 64)
self->s.frame = 16;
else
self->s.frame = 4;
// set the color
if (self->spawnflags & 2)
self->s.skinnum = 0xf2f2f0f0;
else if (self->spawnflags & 4)
self->s.skinnum = 0xd0d1d2d3;
else if (self->spawnflags & 8)
self->s.skinnum = 0xf3f3f1f1;
else if (self->spawnflags & 16)
self->s.skinnum = 0xdcdddedf;
else if (self->spawnflags & 32)
self->s.skinnum = 0xe0e1e2e3;
if (!self->enemy)
{
if (self->target)
{
ent = G_Find(NULL, FOFS(targetname), self->target);
if (!ent)
gi.dprintf("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target);
self->enemy = ent;
}
else
G_SetMovedir(self->s.angles, self->movedir);
}
self->use = target_laser_use;
self->think = target_laser_think;
if (!self->dmg)
self->dmg = 1;
VectorSet(self->mins, -8.0, -8.0, -8.0);
VectorSet(self->maxs, 8.0, 8.0, 8.0);
gi.linkentity(self);
if (self->spawnflags & 1)
target_laser_on(self);
else
target_laser_off(self);
}
void SP_target_laser (edict_t *self)
{
self->think = target_laser_start;
self->nextthink = level.time + 1.0; // let everything else get spawned before we start firing
}
//==========================================================
/*QUAKED target_earthquake (1 0 0) (-8 -8 -8) (8 8 8)
When triggered, this initiates a level-wide earthquake.
All players and monsters are affected.
"speed" severity of the quake (default:200)
"count" duration of the quake (default:5)
*/
void target_earthquake_think(edict_t *self)
{
edict_t *e;
int i;
if (self->last_move_time < level.time)
{
gi.positioned_sound(self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0, ATTN_NONE, 0);
self->last_move_time = level.time + 0.5;
}
for (i = 1, e = g_edicts + i; i < globals.num_edicts; i++, e++)
{
if (!e->inuse)
continue;
if (!e->client)
continue;
if (!e->groundentity)
continue;
e->groundentity = NULL;
e->velocity[0] += crandom()* 150.0;
e->velocity[1] += crandom()* 150.0;
e->velocity[2] = self->speed * (100.0 / e->mass);
}
if (level.time < self->timestamp)
self->nextthink = level.time + FRAMETIME;
}
void target_earthquake_use(edict_t *self, edict_t *other, edict_t *activator)
{
self->timestamp = level.time + self->count;
self->nextthink = level.time + FRAMETIME;
self->activator = activator;
self->last_move_time = 0.0;
}
void SP_target_earthquake(edict_t *self)
{
if (!self->targetname)
gi.dprintf("untargeted %s at %s\n", self->classname, vtos(self->s.origin));
if (!self->count)
self->count = 5;
if (!self->speed)
self->speed = 200.0;
self->svflags |= SVF_NOCLIENT;
self->think = target_earthquake_think;
self->use = target_earthquake_use;
self->noise_index = gi.soundindex("world/quake.wav");
}
//==========================================================
/*QUAKED target_victory (1 0 0) (-8 -8 -8) (8 8 8)
ASSAULT: When triggered, ends the game with a victory for the attacking team.
*/
void target_victory_use(edict_t *self, edict_t *other, edict_t *activator)
{
G_UseTargets(self, activator);
asltgame.victory = true;
}
void SP_target_victory(edict_t *self)
{
if (sv_gametype->value != G_ASLT)
{
G_FreeEdict(self);
return;
}
self->classname = "assault_victory";
self->svflags |= SVF_NOCLIENT;
self->use = target_victory_use;
}
//CW--

5767
awaken2/g_team.c Normal file

File diff suppressed because it is too large Load diff

243
awaken2/g_team.h Normal file
View file

@ -0,0 +1,243 @@
// g_team.h
#define STAT_CTF_TEAM1_PIC 17
#define STAT_CTF_TEAM1_CAPS 18
#define STAT_CTF_TEAM2_PIC 19
#define STAT_CTF_TEAM2_CAPS 20
#define STAT_CTF_FLAG_PIC 21 //CW: (ab)used as an attacking team indicator for Assault
#define STAT_CTF_JOINED_TEAM1_PIC 22
#define STAT_CTF_JOINED_TEAM2_PIC 23
#define STAT_CTF_TEAM1_HEADER 24
#define STAT_CTF_TEAM2_HEADER 25
#define STAT_CTF_TECH 26
#define STAT_CTF_ID_VIEW 27
#define STAT_CTF_MATCH 28
#define STAT_CTF_ID_VIEW_COLOR 29
#define STAT_CTF_TEAMINFO 30
//CW++
#define STAT_ASLT_ATTACK2 31
#define CLIENT_ID_CHECKTIME 0.5
//CW--
#define CONFIG_CTF_MATCH (CS_AIRACCEL-1)
#define CONFIG_CTF_TEAMINFO (CS_AIRACCEL-2)
typedef enum
{
CTF_NOTEAM,
CTF_TEAM1,
CTF_TEAM2,
//CW++
CTF_TEAM_FFA
//CW--
} ctfteam_t;
typedef enum
{
CTF_GRAPPLE_STATE_FLY,
CTF_GRAPPLE_STATE_PULL,
CTF_GRAPPLE_STATE_HANG
} ctfgrapplestate_t;
//CW++
typedef enum match_s
{
MATCH_NONE,
MATCH_SETUP,
MATCH_PREGAME,
MATCH_GAME,
MATCH_POST
} match_t;
//CW--
typedef struct ghost_s
{
char netname[MAX_NAMELEN]; //CW
int number;
int deaths; // stats
int kills; //
int caps; //
int basedef; //
int carrierdef; //
int code; // ghost code
int team; // team
int score; // frags at time of disconnect
edict_t *ent;
} ghost_t;
typedef struct teamgame_s //CW
{
int team1;
int team2;
int total1; // only set when going into intermission!
int total2; // only set when going into intermission!
float last_flag_capture;
int last_capture_team;
match_t match; // match state
float matchtime; // time for match start/end (depends on state)
int lasttime; // last time update
qboolean countdown; // has audio countdown started?
int warnactive; // true if stat string 30 is active
ghost_t ghosts[MAX_CLIENTS]; // ghost codes
//CW++
int frags1; // scores for TDM
int frags2; //
//CW--
} teamgame_t; //CW
//CW++
// Assault game info (NB: teamgame_t is still used for most of the relevant team data).
typedef struct asltgame_s
{
qboolean victory; // attacking team has achieved objective(s)
int t_attack; // attacking team
int spawn; // current spawn point selection
char *msg_attack; // message displayed if the attackers win the level
char *msg_defend; // message displayed if the defenders win the level
} asltgame_t;
//CW--
#define CTF_TEAM1_SKIN "ctf_r"
#define CTF_TEAM2_SKIN "ctf_b"
#define CTF_CAPTURE_BONUS 15 // what you get for capture
#define CTF_TEAM_BONUS 10 // what your team gets for capture
#define CTF_RECOVERY_BONUS 1 // what you get for recovery
#define CTF_FLAG_BONUS 0 // what you get for picking up enemy flag
#define CTF_FRAG_CARRIER_BONUS 2 // what you get for fragging enemy flag carrier
#define CTF_FLAG_RETURN_TIME 40 // seconds until auto return
#define CTF_CARRIER_DANGER_PROTECT_BONUS 2 // bonus for fragging someone who has recently hurt your flag carrier
#define CTF_CARRIER_PROTECT_BONUS 1 // bonus for fragging someone while either you or your target are near your flag carrier
#define CTF_FLAG_DEFENSE_BONUS 1 // bonus for fragging someone while either you or your target are near your flag
#define CTF_RETURN_FLAG_ASSIST_BONUS 1 // awarded for returning a flag that causes a capture to happen almost immediately
#define CTF_FRAG_CARRIER_ASSIST_BONUS 2 // award for fragging a flag carrier if a capture happens almost immediately
#define CTF_TARGET_PROTECT_RADIUS 400 // the radius around an object being defended where a target will be worth extra frags
#define CTF_ATTACKER_PROTECT_RADIUS 400 // the radius around an object being defended where an attacker will get extra frags when making kills
#define CTF_CARRIER_DANGER_PROTECT_TIMEOUT 8
#define CTF_FRAG_CARRIER_ASSIST_TIMEOUT 10
#define CTF_RETURN_FLAG_ASSIST_TIMEOUT 10
#define CTF_AUTO_FLAG_RETURN_TIMEOUT 30 // number of seconds before dropped flag auto-returns
#define CTF_TECH_TIMEOUT 60 // seconds before techs spawn again
void CTFInit(void);
void CTFSpawn(void);
void CTFPrecache(void);
void SP_info_player_team1(edict_t *self);
void SP_info_player_team2(edict_t *self);
char *CTFTeamName(int team);
char *CTFOtherTeamName(int team);
void CTFAssignSkin(edict_t *ent, char *s);
void CTFAssignTeam(gclient_t *who);
edict_t *SelectCTFSpawnPoint (edict_t *ent, qboolean ctf_only); //CW
qboolean CTFPickup_Flag(edict_t *ent, edict_t *other);
void CTFDrop_Flag(edict_t *ent, gitem_t *item); //CW
void CTFEffects(edict_t *player);
void CTFCalcScores(void);
void SetCTFStats(edict_t *ent);
void CTFDeadDropFlag(edict_t *self);
void CTFScoreboardMessage (edict_t *ent, edict_t *killer);
void CTFTeam_f (edict_t *ent);
void CTFID_f (edict_t *ent);
void CTFSay_Team(edict_t *who, char *msg);
void CTFFlagSetup (edict_t *ent);
void CTFResetFlag(int ctf_team);
void CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker);
void CTFCheckHurtCarrier(edict_t *targ, edict_t *attacker);
// GRAPPLE
//CW++
void CTFWeapon_Grapple_OffHand(edict_t *self);
void CTFResetAllPlayers(void);
//CW--
void CTFWeapon_Grapple (edict_t *ent);
void CTFPlayerResetGrapple(edict_t *ent);
void CTFGrapplePull(edict_t *self);
void CTFResetGrapple(edict_t *self);
//TECH
gitem_t *CTFWhat_Tech(edict_t *ent);
qboolean CTFPickup_Tech (edict_t *ent, edict_t *other);
void CTFDrop_Tech(edict_t *ent, gitem_t *item);
void CTFDeadDropTech(edict_t *ent);
void CTFSetupTechSpawn(void);
int CTFApplyResistance(edict_t *ent, int dmg);
int CTFApplyStrength(edict_t *ent, int dmg);
qboolean CTFApplyStrengthSound(edict_t *ent);
qboolean CTFApplyHaste(edict_t *ent);
void CTFApplyHasteSound(edict_t *ent);
void CTFApplyRegeneration(edict_t *ent);
qboolean CTFHasRegeneration(edict_t *ent);
void CTFRespawnTech(edict_t *ent);
void CTFResetTech(void);
void CTFOpenJoinMenu(edict_t *ent);
qboolean CTFStartClient(edict_t *ent);
void CTFVoteYes(edict_t *ent);
void CTFVoteNo(edict_t *ent);
void CTFReady(edict_t *ent);
void CTFNotReady(edict_t *ent);
qboolean CTFNextMap(void);
qboolean CTFMatchSetup(void);
qboolean CTFMatchOn(void);
void CTFGhost(edict_t *ent);
qboolean CTFInMatch(void);
void CTFStats(edict_t *ent);
void CTFBoot(edict_t *ent, qboolean ban); //CW
void CTFPlayerList(edict_t *ent);
qboolean CTFCheckRules(void);
void SP_misc_ctf_banner (edict_t *ent);
void SP_misc_ctf_small_banner (edict_t *ent);
extern char *ctf_statusbar;
void CTFObserver(edict_t *ent);
void SP_trigger_teleport (edict_t *ent);
void SP_info_teleport_destination (edict_t *ent);
void CTFSetPowerUpEffect(edict_t *ent, int def);
//CW++
extern teamgame_t teamgame;
extern asltgame_t asltgame;
//======================================================================
// Team-DM stuff
//======================================================================
extern char *tdm_statusbar;
void TDMPrecache(void);
void TDMScoreboardMessage(edict_t *ent, edict_t *killer);
//======================================================================
// Assault stuff
//======================================================================
#define LINESIZE 23
#define MAX_SPAWNS 32
extern char *aslt_statusbar;
void ASLTPrecache(void);
void ASLTSpawn(void);
void ASLTShowMission(edict_t *ent);
edict_t *SelectASLTSpawnPoint (edict_t *ent);
qboolean ASLTCheckRules(void);
//CW--

569
awaken2/g_trigger.c Normal file
View file

@ -0,0 +1,569 @@
// g_trigger.c
#include "g_local.h"
void InitTrigger(edict_t *self)
{
if (!VectorCompare(self->s.angles, vec3_origin))
G_SetMovedir(self->s.angles, self->movedir);
self->solid = SOLID_TRIGGER;
self->movetype = MOVETYPE_NONE;
gi.setmodel(self, self->model);
self->svflags = SVF_NOCLIENT;
}
// the wait time has passed, so set back up for another activation
void multi_wait(edict_t *ent)
{
ent->nextthink = 0;
}
// the trigger was just activated
// ent->activator should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void multi_trigger(edict_t *ent)
{
if (ent->nextthink)
return; // already been triggered
G_UseTargets(ent, ent->activator);
if (ent->wait > 0.0)
{
ent->think = multi_wait;
ent->nextthink = level.time + ent->wait;
}
else
{ // we can't just remove (self) here, because this is a touch function
// called while looping through area links...
ent->touch = NULL;
ent->nextthink = level.time + FRAMETIME;
ent->think = G_FreeEdict;
}
}
void Use_Multi(edict_t *ent, edict_t *other, edict_t *activator)
{
ent->activator = activator;
multi_trigger(ent);
}
void Touch_Multi(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other->client)
{
if (self->spawnflags & 2)
return;
}
else if (other->svflags & SVF_MONSTER)
{
if (!(self->spawnflags & 1))
return;
}
else
return;
if (!VectorCompare(self->movedir, vec3_origin))
{
vec3_t forward;
AngleVectors(other->s.angles, forward, NULL, NULL);
if (_DotProduct(forward, self->movedir) < 0.0)
return;
}
self->activator = other;
multi_trigger(self);
}
/*QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED
Variable sized repeatable trigger. Must be targeted at one or more entities.
If "delay" is set, the trigger waits some time after activating before firing.
"wait" : Seconds between triggerings. (.2 default)
sounds
1) secret
2) beep beep
3) large switch
set "message" to text string
*/
void trigger_enable(edict_t *self, edict_t *other, edict_t *activator)
{
self->solid = SOLID_TRIGGER;
self->use = Use_Multi;
gi.linkentity(self);
}
void SP_trigger_multiple(edict_t *ent)
{
if (ent->sounds == 1)
ent->noise_index = gi.soundindex("misc/secret.wav");
else if (ent->sounds == 2)
ent->noise_index = gi.soundindex("misc/talk.wav");
else if (ent->sounds == 3)
ent->noise_index = gi.soundindex("misc/trigger1.wav");
if (!ent->wait)
ent->wait = 0.2;
ent->touch = Touch_Multi;
ent->movetype = MOVETYPE_NONE;
ent->svflags |= SVF_NOCLIENT;
if (ent->spawnflags & 4)
{
ent->solid = SOLID_NOT;
ent->use = trigger_enable;
}
else
{
ent->solid = SOLID_TRIGGER;
ent->use = Use_Multi;
}
if (!VectorCompare(ent->s.angles, vec3_origin))
G_SetMovedir(ent->s.angles, ent->movedir);
gi.setmodel(ent, ent->model);
gi.linkentity(ent);
}
/*QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED
Triggers once, then removes itself.
You must set the key "target" to the name of another object in the level that has a matching "targetname".
If TRIGGERED, this trigger must be triggered before it is live.
sounds
1) secret
2) beep beep
3) large switch
"message" string to be displayed when triggered
*/
void SP_trigger_once(edict_t *ent)
{
// make old maps work because I messed up on flag assignments here
// triggered was on bit 1 when it should have been on bit 4
if (ent->spawnflags & 1)
{
vec3_t v;
VectorMA (ent->mins, 0.5, ent->size, v);
ent->spawnflags &= ~1;
ent->spawnflags |= 4;
gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));
}
ent->wait = -1.0;
SP_trigger_multiple(ent);
}
/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
This fixed size trigger cannot be touched, it can only be fired by other events.
*/
void trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator)
{
G_UseTargets(self, activator);
}
void SP_trigger_relay(edict_t *self)
{
self->use = trigger_relay_use;
//CW++
self->svflags |= SVF_NOCLIENT;
//CW--
}
/*
==============================================================================
trigger_key
==============================================================================
*/
/*QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8)
A relay trigger that only fires it's targets if player has the proper key.
Use "item" to specify the required key, for example "key_data_cd"
*/
void trigger_key_use(edict_t *self, edict_t *other, edict_t *activator)
{
int index;
if (!self->item)
return;
if (!activator->client)
return;
index = ITEM_INDEX(self->item);
if (!activator->client->pers.inventory[index])
{
if (level.time < self->touch_debounce_time)
return;
self->touch_debounce_time = level.time + 5.0;
gi_centerprintf (activator, "You need the %s", self->item->pickup_name);
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keytry.wav"), 1, ATTN_NORM, 0);
return;
}
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keyuse.wav"), 1, ATTN_NORM, 0);
activator->client->pers.inventory[index]--; //CW
G_UseTargets(self, activator);
self->use = NULL;
}
void SP_trigger_key(edict_t *self)
{
if (!st.item)
{
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
return;
}
self->item = FindItemByClassname(st.item);
if (!self->item)
{
gi.dprintf("item %s not found for trigger_key at %s\n", st.item, vtos(self->s.origin));
return;
}
if (!self->target)
{
gi.dprintf("%s at %s has no target\n", self->classname, vtos(self->s.origin));
return;
}
gi.soundindex("misc/keytry.wav");
gi.soundindex("misc/keyuse.wav");
self->use = trigger_key_use;
}
/*
==============================================================================
trigger_counter
==============================================================================
*/
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
Acts as an intermediary for an action that takes multiple inputs.
If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
*/
void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (self->count == 0)
return;
self->count--;
if (self->count)
{
if (!(self->spawnflags & 1))
{
gi_centerprintf(activator, "%i more to go...", self->count);
gi.sound(activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
}
return;
}
if (!(self->spawnflags & 1))
{
gi_centerprintf(activator, "Sequence completed!");
gi.sound(activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
}
self->activator = activator;
multi_trigger(self);
}
void SP_trigger_counter(edict_t *self)
{
self->wait = -1.0;
if (!self->count)
self->count = 2;
self->use = trigger_counter_use;
//CW++
self->svflags |= SVF_NOCLIENT;
//CW--
}
/*
==============================================================================
trigger_always
==============================================================================
*/
/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
This trigger will always fire. It is activated by the world.
*/
void SP_trigger_always(edict_t *ent)
{
// we must have some delay to make sure our use targets are present
if (ent->delay < 0.2)
ent->delay = 0.2;
//CW++
ent->svflags |= SVF_NOCLIENT;
//CW--
G_UseTargets(ent, ent);
}
/*
==============================================================================
trigger_push
==============================================================================
*/
#define PUSH_ONCE 1
static int windsound;
void trigger_push_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other->health > 0)
{
VectorScale(self->movedir, self->speed * 10.0, other->velocity);
if (other->client)
{
// don't take falling damage immediately from this
VectorCopy(other->velocity, other->client->oldvelocity);
if (other->fly_sound_debounce_time < level.time)
{
other->fly_sound_debounce_time = level.time + 1.5;
gi.sound(other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
}
}
}
if (self->spawnflags & PUSH_ONCE)
G_FreeEdict(self);
}
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
Pushes the player
"speed" defaults to 1000
*/
void SP_trigger_push(edict_t *self)
{
InitTrigger(self);
windsound = gi.soundindex("misc/windfly.wav"); //CFIXME make this customisable
self->touch = trigger_push_touch;
if (!self->speed)
self->speed = 1000.0;
gi.linkentity(self);
}
/*
==============================================================================
trigger_hurt
==============================================================================
*/
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
Any entity that touches this will be hurt.
It does dmg points of damage each server frame
SILENT supresses playing the sound
SLOW changes the damage rate to once per second
NO_PROTECTION *nothing* stops the damage
"dmg" default 5 (whole numbers only)
*/
void hurt_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (self->solid == SOLID_NOT)
self->solid = SOLID_TRIGGER;
else
self->solid = SOLID_NOT;
gi.linkentity(self);
if (!(self->spawnflags & 2))
self->use = NULL;
}
void hurt_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
int dflags;
if (!other->takedamage)
return;
if (self->timestamp > level.time)
return;
if (self->spawnflags & 16)
self->timestamp = level.time + 1.0;
else
self->timestamp = level.time + FRAMETIME;
if (!(self->spawnflags & 4))
{
if ((level.framenum % 10) == 0)
gi.sound(other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
}
if (self->spawnflags & 8)
dflags = DAMAGE_NO_PROTECTION;
else
dflags = 0;
//CW++
if (other->client && (other->client->agm_enemy != NULL))
T_Damage(other, self, other->client->agm_enemy, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_AGM_TRIG_HURT);
else
//CW--
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
}
void SP_trigger_hurt(edict_t *self)
{
InitTrigger(self);
self->noise_index = gi.soundindex("world/electro.wav");
self->touch = hurt_touch;
if (!self->dmg)
self->dmg = 5;
if (self->spawnflags & 1)
self->solid = SOLID_NOT;
else
self->solid = SOLID_TRIGGER;
if (self->spawnflags & 2)
self->use = hurt_use;
gi.linkentity(self);
}
/*
==============================================================================
trigger_gravity
==============================================================================
*/
/*QUAKED trigger_gravity (.5 .5 .5) ?
Changes the touching entites gravity to
the value of "gravity". 1.0 is standard
gravity for the level.
*/
void trigger_gravity_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
other->gravity = self->gravity;
}
void SP_trigger_gravity(edict_t *self)
{
if (st.gravity == 0)
{
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
G_FreeEdict(self);
return;
}
InitTrigger(self);
self->gravity = atoi(st.gravity);
self->touch = trigger_gravity_touch;
}
//CW++
/*
==============================================================================
trigger_waypoint
==============================================================================
*/
/*QUAKED trigger_waypoint (0 .5 .8) ?
ASSAULT: Selects the set of spawn points the attacking team will respawn at.
Can only be triggered by a member of the attacking team.
Removes itself once triggered.
*/
void Trigger_Waypoint_Touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!other->client)
return;
if (other->client->resp.ctf_team != asltgame.t_attack)
return;
G_UseTargets(self, other);
asltgame.spawn = self->count;
self->touch = NULL;
self->nextthink = level.time + FRAMETIME;
self->think = G_FreeEdict;
}
void SP_trigger_waypoint(edict_t *self)
{
if (sv_gametype->value != G_ASLT)
{
G_FreeEdict(self);
return;
}
InitTrigger(self);
self->touch = Trigger_Waypoint_Touch;
if (self->count < 1)
self->count = 1;
gi.linkentity(self);
}
/*
==============================================================================
trigger_kill
Internal entity used to kill players that enter its bounding box.
Essentially a func_killbox, but without a brush model.
==============================================================================
*/
void Trigger_Kill_Touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!other->client)
return;
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_FORBIDDEN);
}
void SP_trigger_kill(edict_t *self)
{
self->solid = SOLID_TRIGGER;
self->movetype = MOVETYPE_NONE;
self->svflags = SVF_NOCLIENT;
self->touch = Trigger_Kill_Touch;
self->classname = "trigger_kill";
gi.linkentity(self);
}
//CW--

1281
awaken2/g_turret.c Normal file

File diff suppressed because it is too large Load diff

1790
awaken2/g_utils.c Normal file

File diff suppressed because it is too large Load diff

3843
awaken2/g_weapon.c Normal file

File diff suppressed because it is too large Load diff

2
awaken2/game.def Normal file
View file

@ -0,0 +1,2 @@
EXPORTS
GetGameAPI

259
awaken2/game.h Normal file
View file

@ -0,0 +1,259 @@
// game.h -- game dll information visible to server
#define GAME_API_VERSION 3
// edict->svflags
#define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects
#define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision
#define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision
//ZOID++
#define SVF_PROJECTILE 0x00000008 // entity is simple projectile, used for network optimization
#define SVF_GIB 0x00000040 // Knightmare- gib flag
// If an entity is projectile, the model index/x/y/z/pitch/yaw are sent, encoded into
// seven (or eight) bytes. This is to speed up projectiles. Currently, only the
// hyperblaster makes use of this. Use for items that are moving with a constant
// velocity that don't change direction or model.
//ZOID--
// edict->solid values
typedef enum
{
SOLID_NOT, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_BSP // bsp clip, touch on edge
} solid_t;
// Filesytem data types
#ifdef GAME_INCLUDE
typedef int fileHandle_t;
typedef enum {
FS_READ,
FS_WRITE,
FS_APPEND
} fsMode_t;
#endif // GAME_INCLUDE
//===============================================================
// link_t is only used for entity area links now
typedef struct link_s
{
struct link_s *prev;
struct link_s *next;
} link_t;
#define MAX_ENT_CLUSTERS 16
typedef struct edict_s edict_t;
typedef struct gclient_s gclient_t;
#ifndef GAME_INCLUDE
struct gclient_s
{
player_state_t ps; // communicated by server to clients
int ping;
// the game dll can add anything it wants after
// this point in the structure
};
struct edict_s
{
entity_state_t s;
struct gclient_s *client;
qboolean inuse;
int linkcount;
// FIXME: move these fields to a server private sv_entity_t
link_t area; // linked to a division node or leaf
int num_clusters; // if -1, use headnode instead
int clusternums[MAX_ENT_CLUSTERS];
int headnode; // unused if num_clusters != -1
int areanum;
int areanum2;
//================================
int svflags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
vec3_t mins;
vec3_t maxs;
vec3_t absmin;
vec3_t absmax;
vec3_t size;
solid_t solid;
int clipmask;
edict_t *owner;
// the game dll can add anything it wants after
// this point in the structure
};
#endif // GAME_INCLUDE
//===============================================================
//
// functions provided by the main engine
//
typedef struct
{
// special messages
void (*bprintf) (int printlevel, char *fmt, ...);
void (*dprintf) (char *fmt, ...);
void (*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
void (*centerprintf) (edict_t *ent, char *fmt, ...);
void (*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
void (*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
// config strings hold all the index strings, the lightstyles,
// and misc data like the sky definition and cdtrack.
// All of the current configstrings are sent to clients when
// they connect, and changes are sent to all connected clients.
void (*configstring) (int num, char *string);
void (*error) (char *fmt, ...);
// the *index functions create configstrings and some internal server state
int (*modelindex) (char *name);
int (*soundindex) (char *name);
int (*imageindex) (char *name);
void (*setmodel) (edict_t *ent, char *name);
// collision detection
trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
int (*pointcontents) (vec3_t point);
qboolean (*inPVS) (vec3_t p1, vec3_t p2);
qboolean (*inPHS) (vec3_t p1, vec3_t p2);
void (*SetAreaPortalState) (int portalnum, qboolean open);
qboolean (*AreasConnected) (int area1, int area2);
// an entity will never be sent to a client or used for collision
// if it is not passed to linkentity. If the size, position, or
// solidity changes, it must be relinked.
void (*linkentity) (edict_t *ent);
void (*unlinkentity) (edict_t *ent); // call before removing an interactive edict
int (*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
void (*Pmove) (pmove_t *pmove); // player movement code common with client prediction
// network messaging
void (*multicast) (vec3_t origin, multicast_t to);
void (*unicast) (edict_t *ent, qboolean reliable);
void (*WriteChar) (int c);
void (*WriteByte) (int c);
void (*WriteShort) (int c);
void (*WriteLong) (int c);
void (*WriteFloat) (float f);
void (*WriteString) (char *s);
void (*WritePosition) (vec3_t pos); // some fractional bits
void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse
void (*WriteAngle) (float f);
// managed memory allocation
void *(*TagMalloc) (int size, int tag);
void (*TagFree) (void *block);
void (*FreeTags) (int tag);
// console variable interaction
cvar_t *(*cvar) (char *var_name, char *value, int flags);
cvar_t *(*cvar_set) (char *var_name, char *value);
cvar_t *(*cvar_forceset) (char *var_name, char *value);
// ClientCommand and ServerCommand parameter access
int (*argc) (void);
char *(*argv) (int n);
char *(*args) (void); // concatenation of all argv >= 1
// add commands to the server console as if they were typed in
// for map changing, etc
void (*AddCommandString) (char *text);
void (*DebugGraph) (float value, int color);
// Knightmare- support game DLL loading from pak files thru engine
// This can be used to load script files, etc
// Also support open, read/write and closing files
#ifdef KMQUAKE2_ENGINE_MOD
char **(*ListPak) (const char *find, int *num); // Deprecated- DO NOT USE!
int (*LoadFile) (const char *name, void **buf);
void (*FreeFile) (void *buf);
void (*FreeFileList) (char **list, int n);
int (*OpenFile) (const char *name, fileHandle_t *f, fsMode_t mode);
int (*OpenCompressedFile) (const char *zipName, const char *fileName, fileHandle_t *f, fsMode_t mode);
void (*CloseFile) (fileHandle_t f);
int (*FRead) (void *buffer, int size, fileHandle_t f);
int (*FWrite) (const void *buffer, int size, fileHandle_t f);
char *(*GameDir) (void);
char *(*SaveGameDir) (void);
void (*CreatePath) (const char *path);
char **(*GetFileList) (const char *path, const char *extension, int *num);
#endif
} game_import_t;
//
// functions exported by the game subsystem
//
typedef struct
{
int apiversion;
// the init function will only be called when a game starts,
// not each time a level is loaded. Persistant data for clients
// and the server can be allocated in init
void (*Init) (void);
void (*Shutdown) (void);
// each new level entered will cause a call to SpawnEntities
void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
// Read/Write Game is for storing persistant cross level information
// about the world state and the clients.
// WriteGame is called every time a level is exited.
// ReadGame is called on a loadgame.
void (*WriteGame) (char *filename, qboolean autosave);
void (*ReadGame) (char *filename);
// ReadLevel is called after the default map information has been
// loaded with SpawnEntities
void (*WriteLevel) (char *filename);
void (*ReadLevel) (char *filename);
qboolean (*ClientConnect) (edict_t *ent, char *userinfo);
void (*ClientBegin) (edict_t *ent);
void (*ClientUserinfoChanged) (edict_t *ent, char *userinfo);
void (*ClientDisconnect) (edict_t *ent);
void (*ClientCommand) (edict_t *ent);
void (*ClientThink) (edict_t *ent, usercmd_t *cmd);
void (*RunFrame) (void);
// ServerCommand will be called when an "sv <command>" command is issued on the
// server console.
// The game can issue gi.argc() / gi.argv() commands to get the rest
// of the parameters
void (*ServerCommand) (void);
//
// global variables shared between game and server
//
// The edict array is allocated in the game dll so it
// can vary in size from one game to another.
//
// The size will be fixed when ge->Init() is called
struct edict_s *edicts;
int edict_size;
int num_edicts; // current number, <= max_edicts
int max_edicts;
} game_export_t;
game_export_t *GetGameApi(game_import_t *import);

204
awaken2/m_player.h Normal file
View file

@ -0,0 +1,204 @@
// m_player.h
// This file generated by qdata - Do NOT Modify
#define FRAME_stand01 0
#define FRAME_stand02 1
#define FRAME_stand03 2
#define FRAME_stand04 3
#define FRAME_stand05 4
#define FRAME_stand06 5
#define FRAME_stand07 6
#define FRAME_stand08 7
#define FRAME_stand09 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_stand31 30
#define FRAME_stand32 31
#define FRAME_stand33 32
#define FRAME_stand34 33
#define FRAME_stand35 34
#define FRAME_stand36 35
#define FRAME_stand37 36
#define FRAME_stand38 37
#define FRAME_stand39 38
#define FRAME_stand40 39
#define FRAME_run1 40
#define FRAME_run2 41
#define FRAME_run3 42
#define FRAME_run4 43
#define FRAME_run5 44
#define FRAME_run6 45
#define FRAME_attack1 46
#define FRAME_attack2 47
#define FRAME_attack3 48
#define FRAME_attack4 49
#define FRAME_attack5 50
#define FRAME_attack6 51
#define FRAME_attack7 52
#define FRAME_attack8 53
#define FRAME_pain101 54
#define FRAME_pain102 55
#define FRAME_pain103 56
#define FRAME_pain104 57
#define FRAME_pain201 58
#define FRAME_pain202 59
#define FRAME_pain203 60
#define FRAME_pain204 61
#define FRAME_pain301 62
#define FRAME_pain302 63
#define FRAME_pain303 64
#define FRAME_pain304 65
#define FRAME_jump1 66
#define FRAME_jump2 67
#define FRAME_jump3 68
#define FRAME_jump4 69
#define FRAME_jump5 70
#define FRAME_jump6 71
#define FRAME_flip01 72
#define FRAME_flip02 73
#define FRAME_flip03 74
#define FRAME_flip04 75
#define FRAME_flip05 76
#define FRAME_flip06 77
#define FRAME_flip07 78
#define FRAME_flip08 79
#define FRAME_flip09 80
#define FRAME_flip10 81
#define FRAME_flip11 82
#define FRAME_flip12 83
#define FRAME_salute01 84
#define FRAME_salute02 85
#define FRAME_salute03 86
#define FRAME_salute04 87
#define FRAME_salute05 88
#define FRAME_salute06 89
#define FRAME_salute07 90
#define FRAME_salute08 91
#define FRAME_salute09 92
#define FRAME_salute10 93
#define FRAME_salute11 94
#define FRAME_taunt01 95
#define FRAME_taunt02 96
#define FRAME_taunt03 97
#define FRAME_taunt04 98
#define FRAME_taunt05 99
#define FRAME_taunt06 100
#define FRAME_taunt07 101
#define FRAME_taunt08 102
#define FRAME_taunt09 103
#define FRAME_taunt10 104
#define FRAME_taunt11 105
#define FRAME_taunt12 106
#define FRAME_taunt13 107
#define FRAME_taunt14 108
#define FRAME_taunt15 109
#define FRAME_taunt16 110
#define FRAME_taunt17 111
#define FRAME_wave01 112
#define FRAME_wave02 113
#define FRAME_wave03 114
#define FRAME_wave04 115
#define FRAME_wave05 116
#define FRAME_wave06 117
#define FRAME_wave07 118
#define FRAME_wave08 119
#define FRAME_wave09 120
#define FRAME_wave10 121
#define FRAME_wave11 122
#define FRAME_point01 123
#define FRAME_point02 124
#define FRAME_point03 125
#define FRAME_point04 126
#define FRAME_point05 127
#define FRAME_point06 128
#define FRAME_point07 129
#define FRAME_point08 130
#define FRAME_point09 131
#define FRAME_point10 132
#define FRAME_point11 133
#define FRAME_point12 134
#define FRAME_crstnd01 135
#define FRAME_crstnd02 136
#define FRAME_crstnd03 137
#define FRAME_crstnd04 138
#define FRAME_crstnd05 139
#define FRAME_crstnd06 140
#define FRAME_crstnd07 141
#define FRAME_crstnd08 142
#define FRAME_crstnd09 143
#define FRAME_crstnd10 144
#define FRAME_crstnd11 145
#define FRAME_crstnd12 146
#define FRAME_crstnd13 147
#define FRAME_crstnd14 148
#define FRAME_crstnd15 149
#define FRAME_crstnd16 150
#define FRAME_crstnd17 151
#define FRAME_crstnd18 152
#define FRAME_crstnd19 153
#define FRAME_crwalk1 154
#define FRAME_crwalk2 155
#define FRAME_crwalk3 156
#define FRAME_crwalk4 157
#define FRAME_crwalk5 158
#define FRAME_crwalk6 159
#define FRAME_crattak1 160
#define FRAME_crattak2 161
#define FRAME_crattak3 162
#define FRAME_crattak4 163
#define FRAME_crattak5 164
#define FRAME_crattak6 165
#define FRAME_crattak7 166
#define FRAME_crattak8 167
#define FRAME_crattak9 168
#define FRAME_crpain1 169
#define FRAME_crpain2 170
#define FRAME_crpain3 171
#define FRAME_crpain4 172
#define FRAME_crdeath1 173
#define FRAME_crdeath2 174
#define FRAME_crdeath3 175
#define FRAME_crdeath4 176
#define FRAME_crdeath5 177
#define FRAME_death101 178
#define FRAME_death102 179
#define FRAME_death103 180
#define FRAME_death104 181
#define FRAME_death105 182
#define FRAME_death106 183
#define FRAME_death201 184
#define FRAME_death202 185
#define FRAME_death203 186
#define FRAME_death204 187
#define FRAME_death205 188
#define FRAME_death206 189
#define FRAME_death301 190
#define FRAME_death302 191
#define FRAME_death303 192
#define FRAME_death304 193
#define FRAME_death305 194
#define FRAME_death306 195
#define FRAME_death307 196
#define FRAME_death308 197
#define MODEL_SCALE 1.000000

3800
awaken2/p_client.c Normal file

File diff suppressed because it is too large Load diff

842
awaken2/p_hud.c Normal file
View file

@ -0,0 +1,842 @@
// p_hud.c
#include "g_local.h"
/*
======================================================================
INTERMISSION
======================================================================
*/
void MoveClientToIntermission(edict_t *ent)
{
ent->client->showscores = true; //CW
VectorCopy(level.intermission_origin, ent->s.origin);
ent->client->ps.pmove.origin[0] = level.intermission_origin[0] * 8;
ent->client->ps.pmove.origin[1] = level.intermission_origin[1] * 8;
ent->client->ps.pmove.origin[2] = level.intermission_origin[2] * 8;
VectorCopy(level.intermission_angle, ent->client->ps.viewangles);
ent->client->ps.pmove.pm_type = PM_FREEZE;
ent->client->ps.gunindex = 0;
#ifdef KMQUAKE2_ENGINE_MOD
ent->client->ps.gunindex2 = 0;
#endif
ent->client->ps.blend[3] = 0;
ent->client->ps.rdflags &= ~RDF_UNDERWATER;
// Clean up powerup info.
ent->client->quad_framenum = 0;
ent->client->invincible_framenum = 0;
ent->client->breather_framenum = 0;
ent->client->enviro_framenum = 0;
ent->client->grenade_blew_up = false;
ent->client->grenade_time = 0;
//CW++
ent->client->show_gausscharge = false;
ent->client->show_gausstarget = 0;
ent->client->gauss_dmg = 0;
ent->client->gauss_framenum = 0;
ent->client->antibeam_framenum = 0;
ent->client->frozen_framenum = 0;
ent->client->siphon_framenum = 0;
ent->client->needle_framenum = 0;
ent->client->haste_framenum = 0;
ent->client->mod_changeteam = false;
ent->burning = false;
ent->disintegrated = false;
ent->tractored = false;
ent->client->agm_charge = 0;
ent->client->agm_showcharge = false;
ent->client->agm_tripped = false;
ent->client->agm_on = false;
ent->client->agm_push = false;
ent->client->agm_pull = false;
ent->client->held_by_agm = false;
ent->client->flung_by_agm = false;
ent->client->thrown_by_agm = false;
ent->client->agm_target = NULL;
ent->client->agm_enemy = NULL;
if (ent->client->ctf_grapple)
CTFResetGrapple(ent->client->ctf_grapple);
//CW--
ent->viewheight = 0;
ent->s.modelindex = 0;
ent->s.modelindex2 = 0;
ent->s.modelindex3 = 0;
ent->s.modelindex4 = 0; //CW
#ifdef KMQUAKE2_ENGINE_MOD
ent->s.modelindex5 = 0;
ent->s.modelindex6 = 0;
#endif
ent->s.effects = 0;
ent->s.sound = 0;
ent->solid = SOLID_NOT;
// Add the layout.
//Maj++
// don't unicast() to bots!
if (ent->isabot)
return;
//Maj--
DeathmatchScoreboardMessage(ent, NULL); //CW
gi.unicast(ent, true);
}
void BeginIntermission(edict_t *targ)
{
edict_t *ent;
edict_t *client;
edict_t *wep_ent; //CW++
int i;
if (level.intermissiontime)
return; // already activated
//ZOID++
if ((int)sv_gametype->value > G_FFA) //CW
CTFCalcScores();
//ZOID--
game.autosaved = false;
// Respawn any dead clients.
for (i = 0; i < (int)maxclients->value; ++i)
{
client = g_edicts + 1 + i;
if (!client->inuse)
continue;
if (client->health < 1)
Respawn(client);
}
level.intermissiontime = level.time;
level.changemap = targ->map;
level.exitintermission = 0; //CW
// Find an intermission spot.
ent = G_Find(NULL, FOFS(classname), "info_player_intermission");
if (!ent)
{ // the map creator forgot to put in an intermission point...
ent = G_Find(NULL, FOFS(classname), "info_player_start");
if (!ent)
ent = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
}
else
{ // chose one of four spots
i = rand() & 3;
while (i--)
{
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
if (!ent) // wrap around the list
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
}
}
VectorCopy(ent->s.origin, level.intermission_origin);
VectorCopy(ent->s.angles, level.intermission_angle);
//CW++
// Remove weapon entities to avoid server crashes due to delayed player deaths.
for (i = 0; i < globals.num_edicts; ++i)
{
wep_ent = &g_edicts[i];
if (!wep_ent->inuse)
continue;
if ((wep_ent->die == Trap_DieFromDamage) || (wep_ent->die == C4_DieFromDamage))
{
TList_DelNode(wep_ent);
G_FreeEdict(wep_ent);
}
if (wep_ent->wep_proj)
G_FreeEdict(wep_ent);
}
//CW--
// Move all clients to the intermission point.
for (i = 0; i < (int)maxclients->value; ++i)
{
client = g_edicts + 1 + i;
if (!client->inuse)
continue;
//CW++
if (client->isabot)
continue;
//CW--
MoveClientToIntermission(client);
}
}
/*
==================
DeathmatchScoreboardMessage
==================
*/
void DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
{
gclient_t *cl;
edict_t *cl_ent;
char entry[1024];
char string[1400];
char *tag;
char entry2[64]; //CW++
int stringlength;
int i, j, k;
int sorted[MAX_CLIENTS];
int sortedscores[MAX_CLIENTS];
int score;
int total;
int picnum;
int x, y;
//CW++
if (ent->client->showscores || ent->client->showinventory)
{
if (ent->client->show_gausstarget)
ent->client->show_gausstarget = 2;
}
if (ent->client->showscores)
{
//CW--
//ZOID++
if (sv_gametype->value == G_CTF) //CW
{
CTFScoreboardMessage(ent, killer);
return;
}
//ZOID--
//CW++
else if ((sv_gametype->value == G_TDM) || (sv_gametype->value == G_ASLT))
{
TDMScoreboardMessage(ent, killer);
return;
}
//CW--
// sort the clients by score
total = 0;
for (i = 0; i < game.maxclients; i++)
{
cl_ent = g_edicts + 1 + i;
if (!cl_ent->inuse)
continue;
//CW++
if (cl_ent->client->spectator)
continue;
//CW--
score = game.clients[i].resp.score;
for (j = 0; j < total; j++)
{
if (score > sortedscores[j])
break;
}
for (k = total; k > j; k--)
{
sorted[k] = sorted[k-1];
sortedscores[k] = sortedscores[k-1];
}
sorted[j] = i;
sortedscores[j] = score;
total++;
}
//CW++
// Add spectators to the end of the list.
for (i = 0; i < game.maxclients; i++)
{
cl_ent = g_edicts + 1 + i;
if (!cl_ent->inuse)
continue;
if (!cl_ent->client->spectator)
continue;
sorted[total] = i;
sortedscores[total] = 0;
total++;
}
//CW--
// print level name and exit rules
string[0] = 0;
stringlength = (int)strlen(string);
// add the clients in sorted order
if (total > 12)
total = 12;
for (i = 0; i < total; i++)
{
cl = &game.clients[sorted[i]];
cl_ent = g_edicts + 1 + sorted[i];
picnum = gi.imageindex("i_fixme");
x = (i >= 6) ? 160 : 0;
y = 32 + 32 * (i % 6);
// add a dogtag
if (cl_ent == ent)
tag = "tag1";
else if (cl_ent == killer)
tag = "tag2";
else
tag = NULL;
if (tag)
{
Com_sprintf(entry, sizeof(entry), "xv %i yv %i picn %s ", x+32, y, tag);
j = (int)strlen(entry);
if (stringlength + j > 1024)
break;
// strcpy(string + stringlength, entry);
Com_strcpy(string + stringlength, sizeof(string)-stringlength, entry);
stringlength += j;
}
// send the layout
//CW++
if (cl->spectator)
{
Com_sprintf(entry, sizeof(entry), "xv %d yv %d string2 \"%s\" ", x+32, y, cl->pers.netname);
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"(Spectator)\" ", x+32, y+8);
Com_strcat(entry, sizeof(entry), entry2);
if (cl->chase_target)
{
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"Watching:\" ", x+32, y+16);
Com_strcat(entry, sizeof(entry), entry2);
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"%s\" ", x+32, y+24, cl->chase_target->client->pers.netname);
Com_strcat(entry, sizeof(entry), entry2);
}
}
else
//CW--
Com_sprintf(entry, sizeof(entry), "client %i %i %i %i %i %i ", x, y, sorted[i], cl->resp.score, cl->ping, (int)((level.framenum - cl->resp.enterframe)/600));
j = (int)strlen(entry);
if (stringlength + j > 1024)
break;
// strcpy(string + stringlength, entry);
Com_strcpy(string + stringlength, sizeof(string)-stringlength,entry);
stringlength += j;
}
//CW++
}
else
*string = 0;
if (ent->client->show_gausstarget & 1)
ShowGaussTarget(ent, string, sizeof(string));
//CW--
gi.WriteByte(svc_layout);
gi.WriteString(string);
}
/*
==================
DeathmatchScoreboard
Draw instead of help message.
Note that it isn't that hard to overflow the 1400 byte message limit!
==================
*/
void DeathmatchScoreboard(edict_t *ent)
{
//Maj++
// don't unicast() to bots!
if (ent->isabot)
return;
//Maj--
DeathmatchScoreboardMessage(ent, ent->enemy);
gi.unicast(ent, true);
}
/*
==================
Cmd_Score_f
Display the scoreboard
==================
*/
void Cmd_Score_f(edict_t *ent)
{
//CW++
if (ent->isabot)
return;
//CW--
ent->client->showinventory = false;
ent->client->showhelp = false;
//ZOID++
if (ent->client->menu)
PMenu_Close(ent);
//ZOID--
if (ent->client->showscores)
{
ent->client->showscores = false;
ent->client->update_chase = true;
//CW++
if (ent->client->show_gausstarget & 2)
ent->client->show_gausstarget = 1;
//CW--
return;
}
ent->client->showscores = true;
DeathmatchScoreboard(ent);
}
//=======================================================================
//CW++
/*
===============
SetWepIDView
This is a modified version of the CTFSetIDView() function written by Zoid.
===============
*/
void SetWepIDView(edict_t *ent)
{
edict_t *index;
edict_t *check;
vec3_t forward;
vec3_t start;
vec3_t dir;
float dp_best = 0.0;
float dp;
float range;
qboolean finished = false;
// If the player has no C4 or Traps, don't bother.
if (!ent->next_node)
{
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = 0;
return;
}
// Only check every few frames.
if (level.time - ent->client->resp.id_trap_time < TRAP_ID_CHECKTIME)
return;
// Cycle through the player's linked list of C4 and Trap entities to determine which
// visible entity (if any) is closest to the player's facing direction.
ent->client->resp.id_trap_time = level.time;
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = 0;
AngleVectors(ent->client->v_angle, forward, NULL, NULL);
start[0] = ent->s.origin[0];
start[1] = ent->s.origin[1];
start[2] = ent->s.origin[2] + ent->viewheight;
index = ent->next_node;
while (index && !finished)
{
check = index;
if (index->next_node)
index = index->next_node;
else
finished = true;
VectorSubtract(check->s.origin, start, dir);
range = VectorLength(dir);
VectorNormalize(dir);
dp = DotProduct(forward, dir);
if ((dp > dp_best) && (range < TRAP_ID_RANGE) && visible(ent, check))
dp_best = dp;
}
if (dp_best > TRAP_ID_DOTPRODUCT)
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = gi.imageindex("i_no");
}
//CW--
/*
===============
G_SetStats
===============
*/
void G_SetStats(edict_t *ent)
{
gitem_t *item;
int index;
int cells = 0; //CW
int power_armor_type;
// health
ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
ent->client->ps.stats[STAT_HEALTH] = ent->health;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
// ent->client->ps.stats[STAT_MAXHEALTH] = min(max(ent->client->pers.max_health, 0), 10000);
ent->client->ps.stats[STAT_MAXHEALTH] = min(max(ent->max_health, 0), 10000);
#endif
// ammo
if (!ent->client->ammo_index)
{
ent->client->ps.stats[STAT_AMMO_ICON] = 0;
ent->client->ps.stats[STAT_AMMO] = 0;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_MAXAMMO] = 0;
#endif
}
else
{
item = &itemlist[ent->client->ammo_index];
ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex(item->icon);
ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index];
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_MAXAMMO] = min(max(GetMaxAmmoByIndex(ent->client, ent->client->ammo_index), 0), 10000);
#endif
}
// armor
power_armor_type = PowerArmorType(ent);
if (power_armor_type)
{
cells = ent->client->pers.inventory[ITEM_INDEX(FindItem("cells"))];
if (cells == 0)
{ // ran out of cells for power armor
ent->flags &= ~(FL_POWER_SHIELD|FL_POWER_SCREEN);
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
power_armor_type = 0;
}
}
index = ArmorIndex (ent);
if (power_armor_type && (!index || (level.framenum & 8)))
{ // flash between power armor and other armor icon
if (power_armor_type == POWER_ARMOR_SHIELD)
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex("i_powershield");
else // POWER_ARMOR_SCREEN
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powerscreen");
ent->client->ps.stats[STAT_ARMOR] = cells;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_MAXARMOR] = min(max(ent->client->pers.max_cells, 0), 10000);
#endif
}
else if (index)
{
item = GetItemByIndex(index);
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex(item->icon);
ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index];
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_MAXARMOR] = min(max(GetMaxArmorByIndex(index), 0), 10000);
#endif
}
else
{
ent->client->ps.stats[STAT_ARMOR_ICON] = 0;
ent->client->ps.stats[STAT_ARMOR] = 0;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_MAXARMOR] = 0;
#endif
}
// pickup message
if (level.time > ent->client->pickup_msg_time)
{
ent->client->ps.stats[STAT_PICKUP_ICON] = 0;
ent->client->ps.stats[STAT_PICKUP_STRING] = 0;
}
// timers
//CW++
// Show weapon charges before powerups.
if (ent->client->show_gausscharge)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_blaster");
if (ent->client->pers.inventory[ent->client->ammo_index] > 0)
{
ent->client->gauss_dmg = (int)((level.framenum - ent->client->gauss_framenum) / (10.0 * sv_gauss_damage_rate->value));
ent->client->gauss_dmg *= (int)sv_gauss_damage_step->value;
ent->client->gauss_dmg += (int)sv_gauss_damage_base->value;
}
else
ent->client->gauss_dmg = (int)sv_gauss_damage_base->value;
if (ent->client->gauss_dmg > sv_gauss_damage_max->value)
ent->client->gauss_dmg = (int)sv_gauss_damage_max->value;
ent->client->ps.stats[STAT_TIMER] = ent->client->gauss_dmg;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max((int)sv_gauss_damage_max->value, 0), 10000);
#endif
}
else if (ent->client->agm_showcharge)
{
if (ent->client->agm_tripped)
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_refuse");
else
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_agm");
ent->client->ps.stats[STAT_TIMER] = ent->client->agm_charge;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = 100;
#endif
}
//CW--
else if (ent->client->quad_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_quad");
ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(QUAD_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
else if (ent->client->invincible_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_invulnerability");
ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(INVINCIBLE_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
//CW++
else if (ent->client->siphon_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_siphon");
ent->client->ps.stats[STAT_TIMER] = (ent->client->siphon_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(SIPHON_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
else if (ent->client->needle_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_needle");
ent->client->ps.stats[STAT_TIMER] = (ent->client->needle_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(NEEDLE_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
else if (ent->client->haste_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_haste");
ent->client->ps.stats[STAT_TIMER] = (ent->client->haste_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(HASTE_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
//CW--
else if (ent->client->enviro_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_envirosuit");
ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(ENVIROSUIT_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
else if (ent->client->breather_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_rebreather");
ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(BREATHER_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
//CW++
else if (ent->client->antibeam_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("k_datacd");
ent->client->ps.stats[STAT_TIMER] = (ent->client->antibeam_framenum - level.framenum) / 10;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(ANTIBEAM_TIMEOUT_FRAMES / 10, 0), 10000);
#endif
}
//CW--
else
{
ent->client->ps.stats[STAT_TIMER_ICON] = 0;
ent->client->ps.stats[STAT_TIMER] = 0;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
ent->client->ps.stats[STAT_TIMER_RANGE] = 0;
#endif
}
// selected item
if ((ent->client->pers.selected_item == -1) || !ent->client->pers.selected_item) //CW
ent->client->ps.stats[STAT_SELECTED_ICON] = 0;
else
ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex(itemlist[ent->client->pers.selected_item].icon);
ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item;
// layouts
ent->client->ps.stats[STAT_LAYOUTS] = 0;
if ((ent->client->pers.health <= 0) || level.intermissiontime || ent->client->showscores || ent->client->show_gausstarget) //CW
ent->client->ps.stats[STAT_LAYOUTS] |= 1;
if (ent->client->showinventory && (ent->client->pers.health > 0))
ent->client->ps.stats[STAT_LAYOUTS] |= 2;
// frags
ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score;
// help icon / current weapon if not shown
if (ent->client->resp.helpchanged && (level.framenum & 8))
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex("i_help");
else if (((ent->client->pers.hand == CENTER_HANDED) || (ent->client->ps.fov > 91.0)) && ent->client->pers.weapon)
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex(ent->client->pers.weapon->icon);
else
ent->client->ps.stats[STAT_HELPICON] = 0;
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
if (ent->client->pers.weapon) {
ent->client->ps.stats[STAT_WEAPON] = gi.imageindex (ent->client->pers.weapon->icon);
}
else
ent->client->ps.stats[STAT_WEAPON] = 0;
#endif
//ZOID++
SetCTFStats(ent);
//ZOID--
//CW++
if (((int)sv_gametype->value == G_FFA) && ent->client->resp.id_trap)
SetWepIDView(ent);
//CW--
}
//CW++
/*
==================
ShowGaussTarget
Helpful hints for the implementation of this code
were given by Damien "Yaya" Slee.
==================
*/
void ShowGaussTarget (edict_t *ent, char *string, size_t stringSize)
{
edict_t *cl_ent;
edict_t *targ = NULL;
vec3_t targ_vec;
vec3_t forward;
vec3_t right;
vec3_t offset;
vec3_t start;
vec3_t vec;
vec3_t t_ang;
char str_temp[64];
float dist;
float min_dist = WORLD_SIZE; // was 8192.0
int x = 999;
int y = 999;
int i;
// Display the targeting area overlay.
Com_sprintf(str_temp, sizeof(str_temp), "xv 32 yv -4 picn g_scan ");
if ((strlen(string) + strlen(str_temp)) < 1024)
// strcat(string, str_temp);
Com_strcat(string, stringSize, str_temp);
// Search through the list of entities to determine if any live players are in front of us.
// For multiple targets, select the nearest one.
AngleVectors(ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 24.0, 8.0, ent->viewheight-5.0); // NB: should be same as offset in Weapon_GaussPistol_Fire()
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
for (i = 0; i < globals.num_edicts; ++i)
{
cl_ent = &g_edicts[i];
if (!cl_ent->client)
continue;
if (!cl_ent->inuse)
continue;
if (cl_ent->movetype == MOVETYPE_NOCLIP)
continue;
if (cl_ent == ent)
continue;
if (cl_ent->health < 1)
continue;
if (((int)sv_gametype->value > G_FFA) && (ent->client->resp.ctf_team == cl_ent->client->resp.ctf_team))
continue;
VectorSubtract(cl_ent->s.origin, start, vec);
if ((dist = VectorLength(vec)) > sv_gauss_scan_range->value)
continue;
VectorNormalize(vec);
if (DotProduct(vec, forward) > 0.75)
{
if (dist < min_dist)
{
targ = cl_ent;
VectorCopy(vec, targ_vec);
min_dist = dist;
}
}
}
// If a valid target has been found, check that it is within the scanner's field-of-view,
// and if so, position the tracking reticle over them.
if (targ != NULL)
{
vectoangles(targ_vec, t_ang);
x = (int)(GAUSS_AIMCAL * sin(DEG2RAD((ent->client->v_angle[1] - t_ang[1]))));
y = (int)(GAUSS_AIMCAL * sin(DEG2RAD((t_ang[0] - ent->client->v_angle[0]))));
}
else
return;
if ((abs(x) < 70) && (abs(y) < 70))
{
Com_sprintf(str_temp, sizeof(str_temp), "xv %i yv %i picn g_targ ", 136+x, 100+y);
if ((strlen(string) + strlen(str_temp)) < 1024)
// strcat(string, str_temp);
Com_strcat(string, stringSize, str_temp);
if (level.time > targ->delay)
{
targ->delay = level.time + 2.0;
if (targ->target_ent && targ->target_ent->client && targ->target_ent->client->spycam)
{
unicastSound(targ->target_ent, gi.soundindex("weapons/gauss/warn.wav"), 1.0); //r1,CW
targ->target_ent->delay = level.time + 2.0;
}
else
unicastSound(targ, gi.soundindex("weapons/gauss/warn.wav"), 1.0); //r1,CW
}
}
}
//CW--

281
awaken2/p_menu.c Normal file
View file

@ -0,0 +1,281 @@
// p_menu.c
#include "g_local.h"
// Note that the pmenu entries are duplicated. This is so that a static set of pmenu entries
// can be used for multiple clients and changed without interference.
// Note that arg will be freed when the menu is closed; it must be allocated memory.
pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg)
{
pmenuhnd_t *hnd;
pmenu_t *p;
int i;
//CW++
if (ent->isabot)
return NULL;
//CW--
if (!ent->client)
return NULL;
if (ent->client->menu)
{
gi.dprintf("warning, ent already has a menu\n");
PMenu_Close(ent);
}
hnd = gi.TagMalloc(sizeof(*hnd), TAG_LEVEL); //CW
hnd->arg = arg;
hnd->entries = gi.TagMalloc(sizeof(pmenu_t)*num, TAG_LEVEL); //CW
memcpy(hnd->entries, entries, sizeof(pmenu_t) * num);
// duplicate the strings since they may be from static memory
for (i = 0; i < num; i++)
{
if (entries[i].text)
hnd->entries[i].text = strdup(entries[i].text);
}
hnd->num = num;
if ((cur < 0) || !entries[cur].SelectFunc)
{
for (i = 0, p = entries; i < num; i++, p++)
{
if (p->SelectFunc)
break;
}
}
else
i = cur;
if (i >= num)
hnd->cur = -1;
else
hnd->cur = i;
ent->client->showscores = true;
ent->client->inmenu = true;
ent->client->menu = hnd;
PMenu_Do_Update(ent);
gi.unicast(ent, true);
return hnd;
}
void PMenu_Close(edict_t *ent)
{
pmenuhnd_t *hnd;
int i;
if (!ent->client->menu)
return;
hnd = ent->client->menu;
for (i = 0; i < hnd->num; i++)
{
if (hnd->entries[i].text)
free(hnd->entries[i].text);
}
gi.TagFree(hnd->entries); //CW
if (hnd->arg)
gi.TagFree(hnd->arg); //CW
gi.TagFree(hnd); //CW
ent->client->menu = NULL;
ent->client->showscores = false;
}
// only use on pmenu's that have been called with PMenu_Open
void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc)
{
if (entry->text)
free(entry->text);
entry->text = strdup(text);
entry->align = align;
entry->SelectFunc = SelectFunc;
}
void PMenu_Do_Update(edict_t *ent)
{
pmenuhnd_t *hnd;
pmenu_t *p;
char string[1400];
char *t;
int x;
int i;
qboolean alt = false;
size_t stringLen;
if (!ent->client->menu)
{
gi.dprintf("warning: ent has no menu\n");
return;
}
hnd = ent->client->menu;
Com_strcpy(string, sizeof(string), "xv 32 yv 8 picn inventory ");
for (i = 0, p = hnd->entries; i < hnd->num; i++, p++)
{
if (!p->text || !*(p->text))
continue; // blank line
t = p->text;
if (*t == '*')
{
alt = true;
t++;
}
// sprintf(string + strlen(string), "yv %d ", 32 + i * 8);
stringLen = strlen(string);
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "yv %d ", 32 + i * 8);
if (p->align == PMENU_ALIGN_CENTER)
x = 162 - ((int)strlen(t) * 4);
else if (p->align == PMENU_ALIGN_RIGHT)
x = 260 - ((int)strlen(t) * 8);
else
x = 58;
// sprintf(string + strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
stringLen = strlen(string);
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
if (hnd->cur == i) {
// sprintf(string + strlen(string), "string2 \"\x0d%s\" ", t);
stringLen = strlen(string);
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string2 \"\x0d%s\" ", t);
}
else if (alt) {
// sprintf(string + strlen(string), "string2 \"%s\" ", t);
stringLen = strlen(string);
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string2 \"%s\" ", t);
}
else {
// sprintf(string + strlen(string), "string \"%s\" ", t);
stringLen = strlen(string);
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string \"%s\" ", t);
}
alt = false;
}
gi.WriteByte(svc_layout);
gi.WriteString(string);
}
void PMenu_Update(edict_t *ent)
{
if (!ent->client->menu)
{
gi.dprintf("warning: ent has no menu\n");
return;
}
if (level.time - ent->client->menutime >= 1.0)
{
// been a second or more since last update, update now
PMenu_Do_Update(ent);
gi.unicast(ent, true);
ent->client->menutime = level.time;
ent->client->menudirty = false;
}
ent->client->menutime = level.time + 0.2;
ent->client->menudirty = true;
}
void PMenu_Next(edict_t *ent)
{
pmenuhnd_t *hnd;
pmenu_t *p;
int i;
if (!ent->client->menu)
{
gi.dprintf("warning: ent has no menu\n");
return;
}
hnd = ent->client->menu;
if (hnd->cur < 0)
return; // no selectable entries
i = hnd->cur;
p = hnd->entries + hnd->cur;
do
{
i++, p++;
if (i == hnd->num)
i = 0, p = hnd->entries;
if (p->SelectFunc)
break;
} while (i != hnd->cur);
hnd->cur = i;
PMenu_Update(ent);
}
void PMenu_Prev(edict_t *ent)
{
pmenuhnd_t *hnd;
pmenu_t *p;
int i;
if (!ent->client->menu)
{
gi.dprintf("warning: ent has no menu\n");
return;
}
hnd = ent->client->menu;
if (hnd->cur < 0)
return; // no selectable entries
i = hnd->cur;
p = hnd->entries + hnd->cur;
do
{
if (i == 0)
{
i = hnd->num - 1;
p = hnd->entries + i;
}
else
i--, p--;
if (p->SelectFunc)
break;
} while (i != hnd->cur);
hnd->cur = i;
PMenu_Update(ent);
}
void PMenu_Select(edict_t *ent)
{
pmenuhnd_t *hnd;
pmenu_t *p;
if (!ent->client->menu)
{
gi.dprintf("warning: ent has no menu\n");
return;
}
hnd = ent->client->menu;
if (hnd->cur < 0)
return; // no selectable entries
p = hnd->entries + hnd->cur;
if (p->SelectFunc)
p->SelectFunc(ent, hnd);
}

33
awaken2/p_menu.h Normal file
View file

@ -0,0 +1,33 @@
// p_menu.h
enum {
PMENU_ALIGN_LEFT,
PMENU_ALIGN_CENTER,
PMENU_ALIGN_RIGHT
};
typedef struct pmenuhnd_s
{
struct pmenu_s *entries;
int cur;
int num;
void *arg;
} pmenuhnd_t;
typedef void (*SelectFunc_t)(edict_t *ent, pmenuhnd_t *hnd);
typedef struct pmenu_s
{
char *text;
int align;
SelectFunc_t SelectFunc;
} pmenu_t;
pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg);
void PMenu_Close(edict_t *ent);
void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc);
void PMenu_Do_Update(edict_t *ent);
void PMenu_Update(edict_t *ent);
void PMenu_Next(edict_t *ent);
void PMenu_Prev(edict_t *ent);
void PMenu_Select(edict_t *ent);

1631
awaken2/p_view.c Normal file

File diff suppressed because it is too large Load diff

2722
awaken2/p_weapon.c Normal file

File diff suppressed because it is too large Load diff

1521
awaken2/q_shared.c Normal file

File diff suppressed because it is too large Load diff

1070
awaken2/q_shared.h Normal file

File diff suppressed because it is too large Load diff

6
awaken2/readme.txt Normal file
View file

@ -0,0 +1,6 @@
This is the source code to the Awakening II support DLL for KMQuake2.
It supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod,
and also the func_plat2 and func_door_secret2 entities from the Ground Zero mission pack.
Note this source code is under the original "Limited Program Source Code License" from id Software,
NOT the GPL. It should not be mixed with GPLed code.

View file

@ -3815,7 +3815,7 @@ struct {
// strncat(buf, "the blue ");
Q_strncatz(buf, bufSize, "the blue ");
else if (nearteam == CTF_TEAM3)
// strncat(buf, "the blue ");
// strncat(buf, "the green ");
Q_strncatz(buf, bufSize, "the green ");
else
// strncat(buf, "the ");

View file

@ -217,8 +217,8 @@ extern void Info_SetValueForKey ( char * s , char * key , char * value ) ;
extern qboolean Info_Validate ( char * s ) ;
extern void Info_RemoveKey ( char * s , char * key ) ;
extern char * Info_ValueForKey ( char * s , char * key ) ;
extern void Com_strcat ( char * dest , size_t destSize , const char * src ) ;
extern void Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
extern size_t Com_strcat ( char * dest , size_t destSize , const char * src ) ;
extern size_t Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
extern void Com_sprintf ( char * dest , size_t size , char * fmt , ... ) ;
extern int Q_strcasecmp ( char * s1 , char * s2 ) ;
extern int Q_strncasecmp ( char * s1 , char * s2 , size_t n ) ;

View file

@ -1222,50 +1222,81 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
}
void Com_strcpy (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
if (!dest) {
Com_Printf ("Com_strcpy: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcpy: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcpy: dstSize < 1\n");
return;
return 0;
}
strncpy(dest, src, destSize-1);
// strncpy(dest, src, destSize-1);
// dest[destSize-1] = 0;
while (--decSize && *s)
*d++ = *s++;
*d = 0;
dest[destSize-1] = 0;
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
return (s - src - 1 + strlen(s));
else
return (s - src - 1); // returned count excludes NULL terminator
}
void Com_strcat (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcat (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
size_t dLen;
if (!dest) {
Com_Printf ("Com_strcat: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcat: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcat: dstSize < 1\n");
return;
return 0;
}
while (--destSize && *dest)
/* while (--destSize && *dest)
dest++;
if (destSize > 0) {
if (destSize > 0){
while (--destSize && *src)
*dest++ = *src++;
*dest = 0;
}*/
while (--decSize && *d)
d++;
dLen = d - dest;
if (decSize == 0)
return (dLen + strlen(s));
if (decSize > 0) {
while (--decSize && *s)
*d++ = *s++;
*d = 0;
}
dest[destSize-1] = 0;
return (dLen + (s - src)); // returned count excludes NULL terminator
}
/*

View file

@ -303,8 +303,9 @@ char *COM_Parse (char **data_p);
// data is an in/out parm, returns a parsed out token
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
void Com_strcpy (char *dest, size_t destSize, const char *src);
void Com_strcat (char *dest, size_t destSize, const char *src);
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
size_t Com_strcat (char *dest, size_t destSize, const char *src);
void Com_PageInMemory (byte *buffer, int size);

Binary file not shown.

View file

@ -246,8 +246,8 @@ extern void Info_SetValueForKey ( char * s , char * key , char * value ) ;
extern qboolean Info_Validate ( char * s ) ;
extern void Info_RemoveKey ( char * s , char * key ) ;
extern char * Info_ValueForKey ( char * s , char * key ) ;
extern void Com_strcat ( char * dest , size_t destSize , const char * src ) ;
extern void Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
extern size_t Com_strcat ( char * dest , size_t destSize , const char * src ) ;
extern size_t Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
extern void Com_sprintf ( char * dest , size_t size , char * fmt , ... ) ;
extern int Q_strcasecmp ( const char * s1 , const char * s2 ) ;
extern int Q_strncasecmp ( const char * s1 , const char * s2 , size_t n ) ;

View file

@ -1222,50 +1222,82 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
dest[size-1] = 0;
}
void Com_strcpy (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
if (!dest) {
Com_Printf ("Com_strcpy: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcpy: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcpy: dstSize < 1\n");
return;
return 0;
}
strncpy (dest, src, destSize-1);
// strncpy(dest, src, destSize-1);
// dest[destSize-1] = 0;
while (--decSize && *s)
*d++ = *s++;
*d = 0;
dest[destSize-1] = 0;
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
return (s - src - 1 + strlen(s));
else
return (s - src - 1); // returned count excludes NULL terminator
}
void Com_strcat (char *dest, size_t destSize, const char *src)
// Knightmare added
size_t Com_strcat (char *dest, size_t destSize, const char *src)
{
char *d = dest;
const char *s = src;
size_t decSize = destSize;
size_t dLen;
if (!dest) {
Com_Printf ("Com_strcat: NULL dst\n");
return;
return 0;
}
if (!src) {
Com_Printf ("Com_strcat: NULL src\n");
return;
return 0;
}
if (destSize < 1) {
Com_Printf ("Com_strcat: dstSize < 1\n");
return;
return 0;
}
while (--destSize && *dest)
/* while (--destSize && *dest)
dest++;
if (destSize > 0) {
if (destSize > 0){
while (--destSize && *src)
*dest++ = *src++;
*dest = 0;
}*/
while (--decSize && *d)
d++;
dLen = d - dest;
if (decSize == 0)
return (dLen + strlen(s));
if (decSize > 0) {
while (--decSize && *s)
*d++ = *s++;
*d = 0;
}
dest[destSize-1] = 0;
return (dLen + (s - src)); // returned count excludes NULL terminator
}
/*

View file

@ -65,7 +65,7 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
#define Q_vsnprintf vsnprintf
#endif
//Knightmare- whether to include new engine enhancements
// Knightmare- whether to include new engine enhancements
#define KMQUAKE2_ENGINE_MOD
#ifdef KMQUAKE2_ENGINE_MOD
@ -261,8 +261,9 @@ char *COM_Parse (char **data_p);
// data is an in/out parm, returns a parsed out token
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
void Com_strcpy (char *dest, size_t destSize, const char *src);
void Com_strcat (char *dest, size_t destSize, const char *src);
// Knightmare added
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
size_t Com_strcat (char *dest, size_t destSize, const char *src);
void Com_PageInMemory (byte *buffer, int size);