mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
- added NBlood source.
This commit is contained in:
parent
23bc385393
commit
0254bf82d3
207 changed files with 74689 additions and 407 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -53,3 +53,6 @@ project.xcworkspace/
|
|||
*.dSYM/
|
||||
|
||||
.DS_Store
|
||||
Platform/Windows/Build
|
||||
Platform/Windows/Win32
|
||||
Platform/Windows/x64
|
||||
|
|
|
@ -29,6 +29,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "glad.vcxproj", "{6A
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rednukem", "rednukem.vcxproj", "{44C4B4F0-B489-4612-B9C7-A38503B7FB67}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsmackerdec", "libsmackerdec.vcxproj", "{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nblood", "nblood.vcxproj", "{5407CB5A-4B15-41FA-B79B-8B386A14D275}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -101,6 +105,22 @@ Global
|
|||
{44C4B4F0-B489-4612-B9C7-A38503B7FB67}.Release|Win32.Build.0 = Release|Win32
|
||||
{44C4B4F0-B489-4612-B9C7-A38503B7FB67}.Release|x64.ActiveCfg = Release|x64
|
||||
{44C4B4F0-B489-4612-B9C7-A38503B7FB67}.Release|x64.Build.0 = Release|x64
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Debug|x64.Build.0 = Debug|x64
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Release|Win32.Build.0 = Release|Win32
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Release|x64.ActiveCfg = Release|x64
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}.Release|x64.Build.0 = Release|x64
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Debug|x64.Build.0 = Debug|x64
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Release|Win32.Build.0 = Release|Win32
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Release|x64.ActiveCfg = Release|x64
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -114,6 +134,8 @@ Global
|
|||
{32D4CF70-A3D6-4CEA-81D7-64C743980276} = {8BD117A0-7FA2-44B0-88A5-29D6C220601E}
|
||||
{6AC1D997-8DAE-4343-8DD8-DA2A1CA63212} = {8BD117A0-7FA2-44B0-88A5-29D6C220601E}
|
||||
{44C4B4F0-B489-4612-B9C7-A38503B7FB67} = {18C3CB5F-1DE6-4CFE-B7F7-ABE824222E1C}
|
||||
{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45} = {8BD117A0-7FA2-44B0-88A5-29D6C220601E}
|
||||
{5407CB5A-4B15-41FA-B79B-8B386A14D275} = {18C3CB5F-1DE6-4CFE-B7F7-ABE824222E1C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0346D2C0-3EB9-4AFB-973F-2904758D6C02}
|
||||
|
|
207
platform/Windows/libsmackerdec.vcxproj
Normal file
207
platform/Windows/libsmackerdec.vcxproj
Normal file
|
@ -0,0 +1,207 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\BitReader.h" />
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\FileStream.h" />
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\HuffmanVLC.h" />
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\LogError.h" />
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\SmackerDecoder.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\BitReader.cpp" />
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\FileStream.cpp" />
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\HuffmanVLC.cpp" />
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\LogError.cpp" />
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\SmackerDecoder.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{598F0D83-2C1B-4F7C-B04D-7FDD471C8C45}</ProjectGuid>
|
||||
<RootNamespace>libsmackerdec</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="props\build_x64.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="props\build_x64.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="props\build_x86.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="props\build_x86.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\Build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\Build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\Build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\Build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
41
platform/Windows/libsmackerdec.vcxproj.filters
Normal file
41
platform/Windows/libsmackerdec.vcxproj.filters
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files" />
|
||||
<Filter Include="Source Files" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\BitReader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\FileStream.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\HuffmanVLC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\LogError.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\libsmackerdec\include\SmackerDecoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\BitReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\FileStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\HuffmanVLC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\LogError.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\libsmackerdec\src\SmackerDecoder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
365
platform/Windows/nblood.vcxproj
Normal file
365
platform/Windows/nblood.vcxproj
Normal file
|
@ -0,0 +1,365 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{5407CB5A-4B15-41FA-B79B-8B386A14D275}</ProjectGuid>
|
||||
<RootNamespace>nblood</RootNamespace>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>nblood</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="props\build_x64.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="props\build_x64.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="props\build_x86.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="props\build_x86.props" />
|
||||
<Import Project="props\build_common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<OutDir>$(SolutionDir)..\..\</OutDir>
|
||||
<IntDir>$(Platform)\Build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<NMakeIncludeSearchPath>$(NMakeIncludeSearchPath);..\..\source\build\include;..\..\source\mact\include;..\..\source\audiolib\include;..\..\source\enet\include;..\..\platform\windows\include</NMakeIncludeSearchPath>
|
||||
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake /f msvc.mak DEBUG=1 WINBITS=32 RENDERTYPE=SDL</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake /f msvc.mak veryclean all DEBUG=1 WINBITS=32 RENDERTYPE=SDL</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake /f msvc.mak veryclean DEBUG=1 WINBITS=32 RENDERTYPE=SDL</NMakeCleanCommandLine>
|
||||
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">USE_OPENGL;POLYMER;SDL_USEFOLDER;SDL_TARGET=2</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake /f msvc.mak WINBITS=32 RENDERTYPE=SDL</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake /f msvc.mak veryclean all WINBITS=32 RENDERTYPE=SDL</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake /f msvc.mak veryclean WINBITS=32 RENDERTYPE=SDL</NMakeCleanCommandLine>
|
||||
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">USE_OPENGL;POLYMER;SDL_USEFOLDER;SDL_TARGET=2</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nmake /f msvc.mak DEBUG=1 WINBITS=64 RENDERTYPE=SDL</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nmake /f msvc.mak veryclean all DEBUG=1 WINBITS=64 RENDERTYPE=SDL</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nmake /f msvc.mak veryclean DEBUG=1 WINBITS=64 RENDERTYPE=SDL</NMakeCleanCommandLine>
|
||||
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">USE_OPENGL;POLYMER;NOASM;SDL_USEFOLDER;SDL_TARGET=2</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nmake /f msvc.mak WINBITS=64 RENDERTYPE=SDL</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nmake /f msvc.mak veryclean all WINBITS=64 RENDERTYPE=SDL</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nmake /f msvc.mak veryclean WINBITS=64 RENDERTYPE=SDL</NMakeCleanCommandLine>
|
||||
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">USE_OPENGL;POLYMER;NOASM;SDL_USEFOLDER;SDL_TARGET=2</NMakePreprocessorDefinitions>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;RENDERTYPESDL=1;MIXERTYPEWIN=1;SDL_USEFOLDER;SDL_TARGET=2;USE_OPENGL=1;POLYMER=1;STARTUP_WINDOW;USE_LIBVPX;HAVE_VORBIS;HAVE_XMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\blood\rsrc\eduke32_icon.c" />
|
||||
<ClCompile Include="..\..\source\blood\src\actor.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\ai.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aibat.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aibeast.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aiboneel.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aiburn.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aicaleb.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aicerber.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aicult.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aigarg.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aighost.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aigilbst.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aihand.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aihound.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aiinnoc.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aipod.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\airat.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aispid.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aitchern.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aiunicult.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aizomba.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\aizombf.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\asound.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\blood.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\callback.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\choke.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\common.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\config.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\controls.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\credits.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\db.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\demo.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\dude.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\endgame.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\eventq.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\fire.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\fx.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\gamemenu.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\gameutil.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\getopt.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\gib.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\globals.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\gmtimbre.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\inifile.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\iob.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\levels.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\loadsave.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\map2d.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\menu.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\messages.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\midi.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\mirrors.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\misc.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\mpu401.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\music.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\network.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\osdcmd.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\player.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\pqueue.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\qav.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\qheap.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\replace.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\resource.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\screen.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\sectorfx.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\seq.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\sfx.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\sound.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\startwin.game.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\tile.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\trig.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\triggers.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\view.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\warp.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\weapon.cpp" />
|
||||
<ClCompile Include="..\..\source\blood\src\winbits.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="audiolib.vcxproj">
|
||||
<Project>{0029c61b-b63d-4e61-99f2-f4e49aabfc47}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="build.vcxproj">
|
||||
<Project>{dbecb851-5624-4fa8-9a9d-7169d0f12ff1}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="enet.vcxproj">
|
||||
<Project>{a68cc5e4-567a-44c8-94fe-c1de09aeeb40}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="glad.vcxproj">
|
||||
<Project>{6ac1d997-8dae-4343-8dd8-da2a1ca63212}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="libsmackerdec.vcxproj">
|
||||
<Project>{598f0d83-2c1b-4f7c-b04d-7fdd471c8c45}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="libxmp-lite.vcxproj">
|
||||
<Project>{32d4cf70-a3d6-4cea-81d7-64c743980276}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="mact.vcxproj">
|
||||
<Project>{bcde1852-e2c6-4abb-84fb-5cd431764a9a}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\source\blood\rsrc\gameres.rc">
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\source\blood\src\actor.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\ai.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aibat.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aibeast.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aiboneel.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aiburn.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aicaleb.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aicerber.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aicult.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aigarg.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aighost.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aigilbst.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aihand.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aihound.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aiinnoc.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aipod.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\airat.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aispid.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aitchern.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aiunicult.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aizomba.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\aizombf.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\asound.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\blood.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\callback.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\choke.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\common_game.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\config.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\controls.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\credits.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\db.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\demo.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\dude.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\endgame.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\eventq.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\fire.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\function.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\fx.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\gamedefs.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\gamemenu.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\gameutil.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\getopt.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\gib.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\globals.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\map2d.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\menu.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\messages.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\mirrors.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\warp.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\inifile.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\iob.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\levels.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\loadsave.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\midi.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\misc.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\mpu401.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\network.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\osdcmds.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\player.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\pqueue.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\qav.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\qheap.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\replace.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\resource.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\screen.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\sectorfx.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\seq.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\sfx.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\sound.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\startwin.game.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\tile.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\trig.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\triggers.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\view.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\weapon.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\_functio.h" />
|
||||
<ClInclude Include="..\..\source\blood\src\_midi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
485
platform/Windows/nblood.vcxproj.filters
Normal file
485
platform/Windows/nblood.vcxproj.filters
Normal file
|
@ -0,0 +1,485 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\blood\rsrc\eduke32_icon.c">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\blood.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\levels.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\winbits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\startwin.game.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\network.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\osdcmd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\config.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\getopt.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\controls.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\demo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\screen.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\qheap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\resource.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\misc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\inifile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\tile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\trig.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\replace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\globals.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\db.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\iob.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\seq.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\sfx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\dude.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\player.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\sound.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\mpu401.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\music.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\midi.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\gameutil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\pqueue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\eventq.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\callback.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\fx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\actor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\endgame.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\qav.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\triggers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\view.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\sectorfx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\gib.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\weapon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\warp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\mirrors.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\ai.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\gamemenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\menu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\messages.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\map2d.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\asound.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\credits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\choke.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\fire.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aibat.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aibeast.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aiboneel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aiburn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aicaleb.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aicerber.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aicult.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aigarg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aighost.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aigilbst.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aihand.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aihound.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aiinnoc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aipod.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\airat.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aispid.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aitchern.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aizomba.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aizombf.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\loadsave.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\gmtimbre.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\common.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\blood\src\aiunicult.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\source\blood\rsrc\gameres.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\source\blood\src\levels.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\common_game.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\startwin.game.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\network.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\blood.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\_functio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\function.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\gamedefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\getopt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\controls.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\demo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\db.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\actor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\trig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\screen.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\qheap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\misc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\inifile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\tile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\globals.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\replace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\iob.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\seq.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\sfx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\player.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\dude.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\sound.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\midi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\mpu401.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\_midi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\loadsave.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\gameutil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\pqueue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\eventq.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\callback.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\fx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\endgame.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\ai.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\qav.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\triggers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\view.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\sectorfx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\gib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\weapon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\warp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\mirrors.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\gamemenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\menu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\messages.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\map2d.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\asound.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\credits.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\choke.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\fire.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aibat.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aibeast.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aiboneel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aiburn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aicaleb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aicerber.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aicult.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aigarg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aighost.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aigilbst.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aihand.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aihound.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aiinnoc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aipod.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\airat.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aispid.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aitchern.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aizomba.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aizombf.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\osdcmds.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\blood\src\aiunicult.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -6,7 +6,7 @@
|
|||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;RENDERTYPESDL=1;MIXERTYPEWIN=1;SDL_USEFOLDER;SDL_TARGET=2;USE_OPENGL=1;STARTUP_WINDOW;USE_LIBVPX;HAVE_VORBIS;HAVE_XMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>./include;./include/vpx/;./include/sdl2/;../../source/build/include;../../source/mact/include;../../source/audiolib/include;../../source/enet/include;../../source/glad/include;../../source/libxmp-lite/include;../../source/libxmp-lite/include/libxmp-lite</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>./include;./include/vpx/;./include/sdl2/;../../source/build/include;../../source/mact/include;../../source/audiolib/include;../../source/enet/include;../../source/glad/include;../../source/libxmp-lite/include;../../source/libxmp-lite/include/libxmp-lite;../../source/libsmackerdec/include</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;4244;4018;4267</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/J %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
|
|
|
@ -225,7 +225,6 @@
|
|||
<ClCompile Include="..\..\source\rr\src\config.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\common.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\demo.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\file_lib.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\game.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\gamedef.cpp" />
|
||||
<ClCompile Include="..\..\source\rr\src\gameexec.cpp" />
|
||||
|
|
|
@ -272,9 +272,6 @@
|
|||
<ClCompile Include="..\..\source\rr\rsrc\eduke32_icon.c">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\rr\src\file_lib.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\source\rr\rsrc\gameres.rc">
|
||||
|
|
|
@ -67,6 +67,9 @@ enum MV_Errors
|
|||
MV_InvalidFile,
|
||||
};
|
||||
|
||||
void DisableInterrupts(void);
|
||||
void RestoreInterrupts(void);
|
||||
|
||||
extern void (*MV_Printf)(const char *fmt, ...);
|
||||
const char *MV_ErrorString(int32_t ErrorNumber);
|
||||
int32_t MV_VoicePlaying(int32_t handle);
|
||||
|
|
|
@ -53,12 +53,6 @@ typedef struct
|
|||
uint32_t tick;
|
||||
} songposition;
|
||||
|
||||
enum MIDI_Device
|
||||
{
|
||||
MIDIDEVICE_NONE = -1,
|
||||
MIDIDEVICE_MPU = 0,
|
||||
MIDIDEVICE_OPL
|
||||
};
|
||||
|
||||
#define MUSIC_LoopSong ( 1 == 1 )
|
||||
#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
|
||||
|
|
|
@ -96,13 +96,13 @@ float MV_GlobalVolume = 1.f;
|
|||
|
||||
static int32_t lockdepth = 0;
|
||||
|
||||
static FORCE_INLINE void DisableInterrupts(void)
|
||||
void DisableInterrupts(void)
|
||||
{
|
||||
if (!lockdepth++)
|
||||
SoundDriver_Lock();
|
||||
}
|
||||
|
||||
static FORCE_INLINE void RestoreInterrupts(void)
|
||||
void RestoreInterrupts(void)
|
||||
{
|
||||
if (!--lockdepth)
|
||||
SoundDriver_Unlock();
|
||||
|
|
191
source/blood/Dependencies.mak
Normal file
191
source/blood/Dependencies.mak
Normal file
|
@ -0,0 +1,191 @@
|
|||
ai_h=\
|
||||
$(blood_src)/aibat.h \
|
||||
$(blood_src)/aibeast.h \
|
||||
$(blood_src)/aiboneel.h \
|
||||
$(blood_src)/aiburn.h \
|
||||
$(blood_src)/aicaleb.h \
|
||||
$(blood_src)/aicerber.h \
|
||||
$(blood_src)/aicult.h \
|
||||
$(blood_src)/aigarg.h \
|
||||
$(blood_src)/aighost.h \
|
||||
$(blood_src)/aigilbst.h \
|
||||
$(blood_src)/aihand.h \
|
||||
$(blood_src)/aihound.h \
|
||||
$(blood_src)/aiinnoc.h \
|
||||
$(blood_src)/aipod.h \
|
||||
$(blood_src)/airat.h \
|
||||
$(blood_src)/aispid.h \
|
||||
$(blood_src)/aitchern.h \
|
||||
$(blood_src)/aiunicult.h \
|
||||
$(blood_src)/aizomba.h \
|
||||
$(blood_src)/aizombf.h
|
||||
|
||||
common_h=\
|
||||
$(engine_inc)/compat.h \
|
||||
$(engine_inc)/common.h \
|
||||
$(engine_inc)/pragmas.h \
|
||||
$(engine_inc)/build.h \
|
||||
$(engine_inc)/baselayer.h \
|
||||
$(engine_inc)/palette.h \
|
||||
$(engine_inc)/polymer.h \
|
||||
$(engine_inc)/polymost.h \
|
||||
$(engine_inc)/texcache.h \
|
||||
$(engine_inc)/cache1d.h \
|
||||
$(mact_inc)/file_lib.h \
|
||||
$(mact_inc)/keyboard.h \
|
||||
$(mact_inc)/mouse.h \
|
||||
$(mact_inc)/joystick.h \
|
||||
$(mact_inc)/control.h \
|
||||
$(audiolib_inc)/fx_man.h \
|
||||
$(audiolib_inc)/music.h \
|
||||
$(blood_src)/common_game.h \
|
||||
$(blood_src)/blood.h \
|
||||
$(blood_src)/actor.h \
|
||||
$(blood_src)/ai.h \
|
||||
$(blood_src)/al_midi.h \
|
||||
$(blood_src)/asound.h \
|
||||
$(blood_src)/callback.h \
|
||||
$(blood_src)/choke.h \
|
||||
$(blood_src)/config.h \
|
||||
$(blood_src)/controls.h \
|
||||
$(blood_src)/credits.h \
|
||||
$(blood_src)/db.h \
|
||||
$(blood_src)/demo.h \
|
||||
$(blood_src)/dude.h \
|
||||
$(blood_src)/endgame.h \
|
||||
$(blood_src)/eventq.h \
|
||||
$(blood_src)/fire.h \
|
||||
$(blood_src)/function.h \
|
||||
$(blood_src)/fx.h \
|
||||
$(blood_src)/gamedefs.h \
|
||||
$(blood_src)/gamemenu.h \
|
||||
$(blood_src)/getopt.h \
|
||||
$(blood_src)/gib.h \
|
||||
$(blood_src)/globals.h \
|
||||
$(blood_src)/inifile.h \
|
||||
$(blood_src)/iob.h \
|
||||
$(blood_src)/levels.h \
|
||||
$(blood_src)/loadsave.h \
|
||||
$(blood_src)/map2d.h \
|
||||
$(blood_src)/menu.h \
|
||||
$(blood_src)/messages.h \
|
||||
$(blood_src)/midi.h \
|
||||
$(blood_src)/mirrors.h \
|
||||
$(blood_src)/misc.h \
|
||||
$(blood_src)/mpu401.h \
|
||||
$(blood_src)/network.h \
|
||||
$(blood_src)/opl3.h \
|
||||
$(blood_src)/osdcmds.h \
|
||||
$(blood_src)/player.h \
|
||||
$(blood_src)/pqueue.h \
|
||||
$(blood_src)/qav.h \
|
||||
$(blood_src)/qheap.h \
|
||||
$(blood_src)/replace.h \
|
||||
$(blood_src)/resource.h \
|
||||
$(blood_src)/screen.h \
|
||||
$(blood_src)/sectorfx.h \
|
||||
$(blood_src)/seq.h \
|
||||
$(blood_src)/sfx.h \
|
||||
$(blood_src)/sound.h \
|
||||
$(blood_src)/tile.h \
|
||||
$(blood_src)/trig.h \
|
||||
$(blood_src)/triggers.h \
|
||||
$(blood_src)/view.h \
|
||||
$(blood_src)/warp.h \
|
||||
$(blood_src)/tile.h
|
||||
|
||||
$(blood_obj)/blood.$o: $(blood_src)/blood.cpp $(common_h)
|
||||
$(blood_obj)/actor.$o: $(blood_src)/actor.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/ai.$o: $(blood_src)/ai.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aibat.$o: $(blood_src)/aibat.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aibeast.$o: $(blood_src)/aibeast.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aiboneel.$o: $(blood_src)/aiboneel.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aiburn.$o: $(blood_src)/aiburn.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aicaleb.$o: $(blood_src)/aicaleb.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aicerber.$o: $(blood_src)/aicerber.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aicult.$o: $(blood_src)/aicult.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aigarg.$o: $(blood_src)/aigarg.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aighost.$o: $(blood_src)/aighost.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aigilbst.$o: $(blood_src)/aigilbst.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aihand.$o: $(blood_src)/aihand.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aihound.$o: $(blood_src)/aihound.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aiinnoc.$o: $(blood_src)/aiinnoc.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aipod.$o: $(blood_src)/aipod.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/airat.$o: $(blood_src)/airat.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aispid.$o: $(blood_src)/aispid.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aitchern.$o: $(blood_src)/aitchern.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aiunicult.$o: $(blood_src)/aiunicult.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aizomba.$o: $(blood_src)/aizomba.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/aizombf.$o: $(blood_src)/aizombf.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/asound.$o: $(blood_src)/asound.cpp $(common_h)
|
||||
$(blood_obj)/callback.$o: $(blood_src)/callback.cpp $(common_h)
|
||||
$(blood_obj)/choke.$o: $(blood_src)/choke.cpp $(common_h)
|
||||
$(blood_obj)/common.$o: $(blood_src)/common.cpp $(common_h)
|
||||
$(blood_obj)/config.$o: $(blood_src)/config.cpp $(common_h)
|
||||
$(blood_obj)/controls.$o: $(blood_src)/controls.cpp $(common_h)
|
||||
$(blood_obj)/credits.$o: $(blood_src)/credits.cpp $(common_h)
|
||||
$(blood_obj)/db.$o: $(blood_src)/db.cpp $(common_h)
|
||||
$(blood_obj)/demo.$o: $(blood_src)/demo.cpp $(common_h)
|
||||
$(blood_obj)/dude.$o: $(blood_src)/dude.cpp $(common_h)
|
||||
$(blood_obj)/endgame.$o: $(blood_src)/endgame.cpp $(common_h)
|
||||
$(blood_obj)/eventq.$o: $(blood_src)/eventq.cpp $(common_h)
|
||||
$(blood_obj)/fire.$o: $(blood_src)/fire.cpp $(common_h)
|
||||
$(blood_obj)/fx.$o: $(blood_src)/fx.cpp $(common_h)
|
||||
$(blood_obj)/gamemenu.$o: $(blood_src)/gamemenu.cpp $(common_h)
|
||||
$(blood_obj)/gameutil.$o: $(blood_src)/gameutil.cpp $(common_h)
|
||||
$(blood_obj)/getopt.$o: $(blood_src)/getopt.cpp $(common_h)
|
||||
$(blood_obj)/gib.$o: $(blood_src)/gib.cpp $(common_h)
|
||||
$(blood_obj)/globals.$o: $(blood_src)/globals.cpp $(common_h)
|
||||
$(blood_obj)/inifile.$o: $(blood_src)/inifile.cpp $(common_h)
|
||||
$(blood_obj)/iob.$o: $(blood_src)/iob.cpp $(common_h)
|
||||
$(blood_obj)/levels.$o: $(blood_src)/levels.cpp $(common_h)
|
||||
$(blood_obj)/loadsave.$o: $(blood_src)/loadsave.cpp $(common_h)
|
||||
$(blood_obj)/map2d.$o: $(blood_src)/map2d.cpp $(common_h)
|
||||
$(blood_obj)/menu.$o: $(blood_src)/menu.cpp $(common_h)
|
||||
$(blood_obj)/messages.$o: $(blood_src)/messages.cpp $(common_h)
|
||||
$(blood_obj)/mirrors.$o: $(blood_src)/mirrors.cpp $(common_h)
|
||||
$(blood_obj)/misc.$o: $(blood_src)/misc.cpp $(common_h)
|
||||
$(blood_obj)/network.$o: $(blood_src)/network.cpp $(common_h)
|
||||
$(blood_obj)/osdcmd.$o: $(blood_src)/osdcmd.cpp $(common_h)
|
||||
$(blood_obj)/player.$o: $(blood_src)/player.cpp $(common_h)
|
||||
$(blood_obj)/pqueue.$o: $(blood_src)/pqueue.cpp $(common_h)
|
||||
$(blood_obj)/qav.$o: $(blood_src)/qav.cpp $(common_h)
|
||||
$(blood_obj)/qheap.$o: $(blood_src)/qheap.cpp $(common_h)
|
||||
$(blood_obj)/replace.$o: $(blood_src)/replace.cpp $(common_h)
|
||||
$(blood_obj)/resource.$o: $(blood_src)/resource.cpp $(common_h)
|
||||
$(blood_obj)/screen.$o: $(blood_src)/screen.cpp $(common_h)
|
||||
$(blood_obj)/sectorfx.$o: $(blood_src)/sectorfx.cpp $(common_h)
|
||||
$(blood_obj)/seq.$o: $(blood_src)/seq.cpp $(common_h)
|
||||
$(blood_obj)/sfx.$o: $(blood_src)/sfx.cpp $(common_h)
|
||||
$(blood_obj)/sound.$o: $(blood_src)/sound.cpp $(common_h)
|
||||
$(blood_obj)/tile.$o: $(blood_src)/tile.cpp $(common_h)
|
||||
$(blood_obj)/trig.$o: $(blood_src)/trig.cpp $(common_h)
|
||||
$(blood_obj)/triggers.$o: $(blood_src)/triggers.cpp $(common_h)
|
||||
$(blood_obj)/view.$o: $(blood_src)/view.cpp $(common_h) $(ai_h)
|
||||
$(blood_obj)/warp.$o: $(blood_src)/warp.cpp $(common_h)
|
||||
$(blood_obj)/weapon.$o: $(blood_src)/weapon.cpp $(common_h)
|
||||
$(blood_obj)/winbits.$o: $(blood_src)/winbits.cpp
|
||||
|
||||
# misc objects
|
||||
$(blood_obj)/game_icon.$o: $(blood_rsrc)/game_icon.c $(blood_rsrc)/game_icon.ico
|
||||
|
||||
$(blood_obj)/gameres.$o: $(blood_rsrc)/gameres.rc $(blood_src)/startwin.game.h $(blood_rsrc)/game.bmp
|
||||
$(blood_obj)/buildres.$o: $(blood_rsrc)/buildres.rc $(engine_inc)/startwin.editor.h $(blood_rsrc)/build.bmp
|
||||
$(blood_obj)/startwin.game.$o: $(blood_src)/startwin.game.cpp $(blood_h) $(engine_inc)/build.h $(engine_inc)/winlayer.h $(engine_inc)/compat.h
|
||||
$(blood_obj)/startgtk.game.$o: $(blood_src)/startgtk.game.cpp $(blood_h) $(engine_inc)/dynamicgtk.h $(engine_inc)/build.h $(engine_inc)/baselayer.h $(engine_inc)/compat.h
|
||||
|
||||
# mact objects
|
||||
$(mact_obj)/animlib.$o: $(mact_src)/animlib.cpp $(mact_inc)/animlib.h $(engine_inc)/compat.h
|
||||
$(mact_obj)/file_lib.$o: $(mact_src)/file_lib.cpp $(mact_inc)/file_lib.h
|
||||
$(mact_obj)/control.$o: $(mact_src)/control.cpp $(mact_inc)/control.h $(mact_inc)/keyboard.h $(mact_inc)/mouse.h $(mact_inc)/joystick.h $(engine_inc)/baselayer.h
|
||||
$(mact_obj)/keyboard.$o: $(mact_src)/keyboard.cpp $(mact_inc)/keyboard.h $(engine_inc)/compat.h $(engine_inc)/baselayer.h
|
||||
$(mact_obj)/joystick.$o: $(mact_src)/joystick.cpp $(mact_inc)/joystick.h $(engine_inc)/baselayer.h
|
||||
$(mact_obj)/scriplib.$o: $(mact_src)/scriplib.cpp $(mact_inc)/scriplib.h $(mact_src)/_scrplib.h $(engine_inc)/compat.h
|
||||
|
||||
$(blood_obj)/al_midi.$o: $(blood_src)/al_midi.cpp $(engine_inc)/compat.h $(blood_src)/al_midi.h $(blood_src)/_al_midi.h $(blood_src)/opl3.h
|
||||
$(blood_obj)/gmtimbre.$o: $(blood_src)/gmtimbre.cpp
|
||||
$(blood_obj)/opl3.$o: $(blood_src)/opl3.cpp
|
||||
$(blood_obj)/midi.$o: $(blood_src)/midi.cpp $(blood_src)/_midi.h $(blood_src)/midi.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h
|
||||
$(blood_obj)/oplmidi.$o: $(blood_src)/oplmidi.cpp $(blood_src)/_oplmidi.h $(blood_src)/oplmidi.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h
|
||||
$(blood_obj)/mpu401.$o: $(blood_src)/mpu401.cpp $(blood_src)/mpu401.h $(audiolib_inc)/music.h
|
||||
$(blood_obj)/music.$o: $(blood_src)/music.cpp $(blood_src)/midi.h $(blood_src)/mpu401.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h
|
339
source/blood/gpl-2.0.txt
Normal file
339
source/blood/gpl-2.0.txt
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
BIN
source/blood/rsrc/build.bmp
Normal file
BIN
source/blood/rsrc/build.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
1
source/blood/rsrc/build_icon.c
Normal file
1
source/blood/rsrc/build_icon.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "eduke32_icon.c"
|
BIN
source/blood/rsrc/build_icon.ico
Normal file
BIN
source/blood/rsrc/build_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
72
source/blood/rsrc/buildres.rc
Normal file
72
source/blood/rsrc/buildres.rc
Normal file
|
@ -0,0 +1,72 @@
|
|||
#define NEED_COMMCTRL_H
|
||||
#include "../../build/include/windows_inc.h"
|
||||
#include "../../build/include/startwin.editor.h"
|
||||
|
||||
RSRC_ICON ICON "build_icon.ico"
|
||||
RSRC_BMP BITMAP "build.bmp"
|
||||
|
||||
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
|
||||
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
|
||||
CAPTION "Startup"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
|
||||
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
|
||||
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
|
||||
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
|
||||
|
||||
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
|
||||
END
|
||||
|
||||
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "&2D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 8, 50, 8
|
||||
CONTROL "", IDC2DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 6, 80, 56
|
||||
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 8, 49, 10
|
||||
CONTROL "&3D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 24, 50, 8
|
||||
CONTROL "", IDC3DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 22, 80, 56
|
||||
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
|
||||
END
|
||||
|
||||
#define FILEVER 1,9,9,9
|
||||
#define PRODUCTVER 1,9,9,9
|
||||
#define STRFILEVER "2.0.0devel\0"
|
||||
#define STRPRODUCTVER "2.0.0devel\0"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION FILEVER
|
||||
PRODUCTVERSION PRODUCTVER
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x3L
|
||||
#else
|
||||
FILEFLAGS 0x2L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "Mapster32 for EDuke32"
|
||||
VALUE "FileVersion", STRFILEVER
|
||||
VALUE "InternalName", "Mapster32"
|
||||
VALUE "LegalCopyright", "Copyright © 2018 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
|
||||
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
|
||||
VALUE "OriginalFilename", "mapster32.exe"
|
||||
VALUE "ProductName", "Mapster32"
|
||||
VALUE "ProductVersion", STRPRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
1 24 "manifest.build.xml"
|
20
source/blood/rsrc/eduke32_icon.c
Normal file
20
source/blood/rsrc/eduke32_icon.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
#include "sdl_inc.h"
|
||||
#include "sdlappicon.h"
|
||||
|
||||
static Uint8 sdlappicon_pixels[] = {
|
||||
#if defined _WIN32 && SDL_MAJOR_VERSION==1
|
||||
# include "eduke32_icon_32px.c"
|
||||
#else
|
||||
# include "eduke32_icon_48px.c"
|
||||
#endif
|
||||
};
|
||||
|
||||
struct sdlappicon sdlappicon = {
|
||||
#if defined _WIN32 && SDL_MAJOR_VERSION==1
|
||||
32,32,
|
||||
#else
|
||||
48,48,
|
||||
#endif
|
||||
sdlappicon_pixels
|
||||
};
|
196
source/blood/rsrc/eduke32_icon_32px.c
Normal file
196
source/blood/rsrc/eduke32_icon_32px.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/* GIMP RGBA C-Source image dump (eduke32_icon_32px.c) */
|
||||
#if 0
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[32 * 32 * 4 + 1];
|
||||
} sdlappicon = {
|
||||
32, 32, 4,
|
||||
#endif
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\313\035\035\033\303\034\034]\311\034\034\225\340''\301\343<<\330\345JJ"
|
||||
"\346\345JJ\346\342\065\065\330\337\040\040\301\314\035\035\225\303\034\034]\275\032"
|
||||
"\032\033\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\302\033\033\062\320\035\035\240\345JJ\351\360\231\231\377\366\305\305\377"
|
||||
"\372\341\341\377\375\364\364\377\375\360\360\377\373\343\343\377\365\272"
|
||||
"\272\377\361\236\236\377\356\213\213\377\352mm\377\342\071\071\351\320\035\035"
|
||||
"\240\302\033\033\062\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\257\030\030\007\311"
|
||||
"\034\034\214\343AA\371\363\253\253\377\374\357\357\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\371\371"
|
||||
"\377\373\346\346\377\370\323\323\377\365\270\270\377\363\254\254\377\363"
|
||||
"\262\262\377\360\231\231\377\344EE\371\302\033\033\214\257\030\030\007\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\313\035\035\062\322\036\036\320\353rr\377\366\301\301\377\371\330\330"
|
||||
"\377\376\371\371\377\376\375\375\377\374\355\355\377\366\305\305\377\361"
|
||||
"\236\236\377\356\207\207\377\355\202\202\377\356\215\215\377\363\256\256"
|
||||
"\377\370\315\315\377\370\315\315\377\370\323\323\377\370\325\325\377\372"
|
||||
"\341\341\377\361\236\236\377\325\036\036\320\302\033\033\062\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\307\034\034/\331\037"
|
||||
"\037\350\353rr\377\360\235\235\377\363\262\262\377\374\353\353\377\367\307"
|
||||
"\307\377\354{{\377\345JJ\377\341\064\064\377\340++\377\332\037\037\377\314\035"
|
||||
"\035\377\303\034\034\377\313\035\035\377\340%%\377\351ff\377\366\277\277\377\374"
|
||||
"\357\357\377\374\351\351\377\376\375\375\377\366\277\277\377\340''\350\302"
|
||||
"\033\033/\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\314\035\035"
|
||||
",\327\036\036\360\351ll\377\354{{\377\365\272\272\377\370\317\317\377\347\\"
|
||||
"\\\377\314\035\035\377\322\036\036\377\340++\377\341\064\064\377\342\065\065\377"
|
||||
"\341\062\062\377\336\037\037\377\313\035\035\377\302\033\033\377\275\032\032\377\302"
|
||||
"\033\033\377\314\035\035\377\351jj\377\374\353\353\377\376\375\375\377\376\375"
|
||||
"\375\377\370\321\321\377\340%%\360\302\033\033,\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\237\026\026\005\320\035\035\322\351ff\377\353tt\377\363\253\253\377"
|
||||
"\366\277\277\377\342\065\065\377\322\036\036\377\303\034\034\377\332\037\037\377"
|
||||
"\342\065\065\377\343<<\377\343<<\377\342\065\065\377\337\040\040\377\320\035\035"
|
||||
"\377\305\034\034\377\302\033\033\377\313\035\035\377\302\033\033\377\311\034\034\377"
|
||||
"\346OO\377\371\334\334\377\375\366\366\377\371\330\330\377\361\236\236\377"
|
||||
"\325\036\036\322\237\026\026\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\303\034\034\213"
|
||||
"\350ee\377\360\225\225\377\365\270\270\377\365\272\272\377\307\034\034\377"
|
||||
"\303\034\034\377\307\034\034\377\347WW\377\347WW\377\337\040\040\377\342\065\065"
|
||||
"\377\342\067\067\377\340--\377\336\037\037\377\313\035\035\377\305\034\034\377\302"
|
||||
"\033\033\377\340--\377\347XX\377\337\040\040\377\322\036\036\377\340''\377\367"
|
||||
"\312\312\377\372\341\341\377\367\310\310\377\354yy\377\302\033\033\213\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\302\033\033+\342\065\065\372\363\256\256\377\363\253\253"
|
||||
"\377\370\321\321\377\331\037\037\377\276\033\033\377\271\032\032\377\350ee\377"
|
||||
"\374\357\357\377\367\307\307\377\320\035\035\377\262\031\031\377\242\027\027\377"
|
||||
"\223\025\025\377\217\024\024\377\235\026\026\377\251\030\030\377\302\033\033\377\360"
|
||||
"\225\225\377\376\373\373\377\355\204\204\377\320\035\035\377\275\032\032\377"
|
||||
"\341..\377\371\330\330\377\365\270\270\377\363\253\253\377\342\067\067\372"
|
||||
"\307\034\034+\000\000\000\000\000\000\000\000\314\035\035\242\357\224\224\377\367\307\307\377"
|
||||
"\372\341\341\377\347WW\377\322\036\036\377\303\034\034\377\350__\377\373\346"
|
||||
"\346\377\355\204\204\377\361\244\244\377\342\071\071\377z\021\021\377w\020\020"
|
||||
"\377w\020\020\377w\020\020\377z\021\021\377w\020\020\377\244\027\027\377\364\263\263"
|
||||
"\377\374\351\351\377\376\373\373\377\353tt\377\275\032\032\377\313\035\035\377"
|
||||
"\346SS\377\370\323\323\377\360\231\231\377\353xx\377\320\035\035\242\000\000\000"
|
||||
"\000\307\034\034\026\343<<\361\367\310\310\377\372\337\337\377\366\277\277\377"
|
||||
"\302\033\033\377\311\034\034\377\343@@\377\373\346\346\377\356\211\211\377\340"
|
||||
"--\377\366\277\277\377\370\323\323\377\223\025\025\377|\021\021\377|\021\021\377"
|
||||
"|\021\021\377w\020\020\377z\021\021\377\354}}\377\367\310\310\377\347WW\377\370"
|
||||
"\323\323\377\374\357\357\377\343@@\377\322\036\036\377\302\033\033\377\364\263"
|
||||
"\263\377\364\263\263\377\360\227\227\377\341\062\062\361\307\034\034\026\302\033"
|
||||
"\033\\\353xx\377\367\312\312\377\373\344\344\377\351ll\377\275\032\032\377\313"
|
||||
"\035\035\377\365\272\272\377\371\334\334\377\345HH\377\363\262\262\377\376"
|
||||
"\373\373\377\376\373\373\377\353rr\377z\021\021\377|\021\021\377|\021\021\377z"
|
||||
"\021\021\377\244\027\027\377\375\366\366\377\376\373\373\377\364\267\267\377"
|
||||
"\345JJ\377\370\325\325\377\363\260\260\377\302\033\033\377\322\036\036\377\350"
|
||||
"]]\377\370\315\315\377\361\236\236\377\351ff\377\303\034\034\\\313\035\035\227"
|
||||
"\357\220\220\377\367\310\310\377\370\323\323\377\340))\377\302\033\033\377"
|
||||
"\347WW\377\376\373\373\377\360\233\233\377\353vv\377\376\373\373\377\376"
|
||||
"\373\373\377\376\373\373\377\375\362\362\377\244\027\027\377\214\023\023\377"
|
||||
"\235\026\026\377\217\024\024\377\353rr\377\376\373\373\377\376\373\373\377\376"
|
||||
"\373\373\377\353tt\377\353vv\377\373\346\346\377\343AA\377\311\034\034\377"
|
||||
"\331\037\037\377\367\312\312\377\363\256\256\377\355\202\202\377\313\035\035"
|
||||
"\227\337\040\040\303\361\236\236\377\370\323\323\377\362\245\245\377\311\034"
|
||||
"\034\377\275\032\032\377\357\220\220\377\374\353\353\377\347ZZ\377\371\330\330"
|
||||
"\377\376\373\373\377\376\373\373\377\376\373\373\377\376\373\373\377\372"
|
||||
"\337\337\377\373\346\346\377\376\373\373\377\367\307\307\377\376\373\373"
|
||||
"\377\376\373\373\377\376\373\373\377\376\373\373\377\371\330\330\377\345"
|
||||
"HH\377\370\325\325\377\356\213\213\377\311\034\034\377\276\033\033\377\362\247"
|
||||
"\247\377\367\307\307\377\360\225\225\377\340%%\303\342\067\067\330\363\262"
|
||||
"\262\377\372\335\335\377\356\215\215\377\275\032\032\377\313\035\035\377\364"
|
||||
"\265\265\377\366\277\277\377\343AA\377\376\373\373\377\376\373\373\377\376"
|
||||
"\373\373\377\376\373\373\377\376\373\373\377\376\373\373\377\372\341\341"
|
||||
"\377\366\305\305\377\376\373\373\377\376\373\373\377\376\373\373\377\376"
|
||||
"\373\373\377\376\373\373\377\376\373\373\377\343AA\377\364\265\265\377\363"
|
||||
"\262\262\377\305\034\034\377\303\034\034\377\356\213\213\377\370\323\323\377"
|
||||
"\363\253\253\377\342\071\071\330\344GG\346\367\314\314\377\373\346\346\377"
|
||||
"\355\202\202\377\275\032\032\377\336\037\037\377\371\330\330\377\370\321\321"
|
||||
"\377\357\224\224\377\376\373\373\377\376\373\373\377\376\373\373\377\376"
|
||||
"\373\373\377\376\373\373\377\366\277\277\377\217\024\024\377z\021\021\377\337"
|
||||
"\"\"\377\375\366\366\377\376\373\373\377\376\373\373\377\376\373\373\377"
|
||||
"\376\373\373\377\357\220\220\377\367\310\310\377\370\325\325\377\325\036\036"
|
||||
"\377\303\034\034\377\354}}\377\372\335\335\377\364\267\267\377\343AA\346\345"
|
||||
"JJ\346\371\332\332\377\375\360\360\377\355\206\206\377\307\034\034\377\337"
|
||||
"\040\040\377\355\206\206\377\360\235\235\377\353vv\377\352qq\377\353rr\377"
|
||||
"\353rr\377\354}}\377\376\373\373\377\353vv\377w\020\020\377w\020\020\377\214"
|
||||
"\023\023\377\376\367\367\377\371\330\330\377\353rr\377\353rr\377\352qq\377"
|
||||
"\353vv\377\357\220\220\377\353vv\377\311\034\034\377\303\034\034\377\354}}\377"
|
||||
"\371\332\332\377\364\267\267\377\344EE\346\343AA\330\371\330\330\377\376"
|
||||
"\367\367\377\360\225\225\377\331\037\037\377\337\040\040\377\325\036\036\377\313"
|
||||
"\035\035\377\230\025\025\377w\020\020\377z\021\021\377p\020\020\377\217\024\024\377\373"
|
||||
"\350\350\377\375\362\362\377\235\026\026\377|\021\021\377\346UU\377\376\373\373"
|
||||
"\377\342\071\071\377z\021\021\377z\021\021\377w\020\020\377\217\024\024\377\302\033"
|
||||
"\033\377\275\032\032\377\302\033\033\377\275\032\032\377\356\213\213\377\370\325"
|
||||
"\325\377\363\254\254\377\342\071\071\330\340))\303\367\312\312\377\376\367"
|
||||
"\367\377\364\263\263\377\337$$\377\337\040\040\377\337\"\"\377\336\037\037\377"
|
||||
"\260\031\031\377w\020\020\377|\021\021\377z\021\021\377z\021\021\377\345JJ\377\376"
|
||||
"\373\373\377\375\366\366\377\374\351\351\377\376\373\373\377\371\332\332"
|
||||
"\377\235\026\026\377|\021\021\377|\021\021\377w\020\020\377\251\030\030\377\307\034"
|
||||
"\034\377\311\034\034\377\302\033\033\377\311\034\034\377\362\247\247\377\370\323"
|
||||
"\323\377\361\236\236\377\340%%\303\313\035\035\227\363\262\262\377\375\362"
|
||||
"\362\377\372\335\335\377\341\064\064\377\320\035\035\377\331\037\037\377\325\036"
|
||||
"\036\377\302\033\033\377~\021\021\377w\020\020\377|\021\021\377w\020\020\377\212\023"
|
||||
"\023\377\362\245\245\377\376\373\373\377\376\373\373\377\376\373\373\377\337"
|
||||
"\"\"\377z\021\021\377|\021\021\377w\020\020\377~\021\021\377\275\032\032\377\305\034"
|
||||
"\034\377\311\034\034\377\276\033\033\377\337$$\377\370\321\321\377\366\305\305"
|
||||
"\377\357\220\220\377\313\035\035\227\275\032\032\\\355\202\202\377\372\341\341"
|
||||
"\377\374\351\351\377\351jj\377\275\032\032\377\314\035\035\377\302\033\033\377"
|
||||
"\276\033\033\377\250\030\030\377w\020\020\377z\021\021\377z\021\021\377\244\027\027\377"
|
||||
"\375\362\362\377\376\373\373\377\376\373\373\377\376\373\373\377\362\245"
|
||||
"\245\377z\021\021\377w\020\020\377w\020\020\377\244\027\027\377\276\033\033\377\276"
|
||||
"\033\033\377\302\033\033\377\303\034\034\377\350__\377\371\330\330\377\365\270"
|
||||
"\270\377\353tt\377\302\033\033\\\307\034\034\026\343<<\361\366\305\305\377\371"
|
||||
"\332\332\377\365\272\272\377\275\032\032\377\302\033\033\377\275\032\032\377\276"
|
||||
"\033\033\377\276\033\033\377\237\026\026\377z\021\021\377\217\024\024\377\375\362\362"
|
||||
"\377\376\373\373\377\376\373\373\377\376\373\373\377\376\373\373\377\376"
|
||||
"\373\373\377\346OO\377z\021\021\377\237\026\026\377\276\033\033\377\275\032\032\377"
|
||||
"\275\032\032\377\302\033\033\377\303\034\034\377\365\270\270\377\366\305\305\377"
|
||||
"\363\253\253\377\342\067\067\361\307\034\034\026\000\000\000\000\313\035\035\242\355\206"
|
||||
"\206\377\363\262\262\377\371\326\326\377\346QQ\377\311\034\034\377\275\032\032"
|
||||
"\377\275\032\032\377\276\033\033\377\276\033\033\377\232\026\026\377\346OO\377\372"
|
||||
"\341\341\377\376\373\373\377\376\373\373\377\376\373\373\377\376\373\373"
|
||||
"\377\372\335\335\377\366\277\277\377\260\031\031\377\302\033\033\377\276\033\033"
|
||||
"\377\276\033\033\377\275\032\032\377\320\035\035\377\345NN\377\370\325\325\377"
|
||||
"\361\244\244\377\355\202\202\377\320\035\035\242\000\000\000\000\000\000\000\000\302\033\033"
|
||||
"+\340--\372\361\236\236\377\362\251\251\377\371\330\330\377\337\040\040\377"
|
||||
"\311\034\034\377\275\032\032\377\276\033\033\377\275\032\032\377\347ZZ\377\371\334"
|
||||
"\334\377\347\\\\\377\347WW\377\351ff\377\351ff\377\350__\377\343AA\377\365"
|
||||
"\272\272\377\370\315\315\377\307\034\034\377\275\032\032\377\275\032\032\377\313"
|
||||
"\035\035\377\337\040\040\377\370\323\323\377\360\235\235\377\360\235\235\377"
|
||||
"\342\067\067\372\307\034\034+\000\000\000\000\000\000\000\000\000\000\000\000\302\033\033\213\350aa\377"
|
||||
"\362\247\247\377\367\310\310\377\366\305\305\377\322\036\036\377\311\034\034"
|
||||
"\377\276\033\033\377\275\032\032\377\357\217\217\377\376\373\373\377\373\350"
|
||||
"\350\377\370\317\317\377\370\315\315\377\370\315\315\377\370\315\315\377"
|
||||
"\374\351\351\377\376\367\367\377\363\262\262\377\325\036\036\377\275\032\032"
|
||||
"\377\313\035\035\377\322\036\036\377\367\307\307\377\367\307\307\377\360\231"
|
||||
"\231\377\351jj\377\311\034\034\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\237\026\026"
|
||||
"\005\320\035\035\322\353xx\377\360\227\227\377\366\277\277\377\367\310\310\377"
|
||||
"\341\062\062\377\311\034\034\377\276\033\033\377\325\036\036\377\345JJ\377\357\217"
|
||||
"\217\377\364\265\265\377\370\315\315\377\370\315\315\377\364\265\265\377"
|
||||
"\357\217\217\377\345JJ\377\302\033\033\377\275\032\032\377\313\035\035\377\343"
|
||||
"<<\377\367\310\310\377\366\305\305\377\360\235\235\377\355\202\202\377\327"
|
||||
"\036\036\322\237\026\026\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\307\034\034"
|
||||
",\332\037\037\360\356\207\207\377\360\235\235\377\370\315\315\377\371\326\326"
|
||||
"\377\347\\\\\377\302\033\033\377\275\032\032\377\302\033\033\377\275\032\032\377"
|
||||
"\320\035\035\377\337\040\040\377\337\"\"\377\320\035\035\377\275\032\032\377\311"
|
||||
"\034\034\377\303\034\034\377\275\032\032\377\347\\\\\377\371\334\334\377\370\315"
|
||||
"\315\377\361\236\236\377\360\225\225\377\340%%\360\307\034\034,\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\307\034\034/\336\037\037\350\355"
|
||||
"\202\202\377\363\262\262\377\365\274\274\377\373\344\344\377\366\277\277"
|
||||
"\377\352oo\377\341\062\062\377\320\035\035\377\307\034\034\377\302\033\033\377\302"
|
||||
"\033\033\377\307\034\034\377\314\035\035\377\340--\377\351ll\377\364\267\267\377"
|
||||
"\371\334\334\377\365\270\270\377\364\267\267\377\356\215\215\377\337$$\350"
|
||||
"\307\034\034/\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\307\034\034\062\322\036\036\320\353tt\377\366\301\301\377\367\312\312"
|
||||
"\377\372\341\341\377\373\346\346\377\370\325\325\377\363\256\256\377\360"
|
||||
"\231\231\377\356\207\207\377\356\207\207\377\360\235\235\377\363\262\262"
|
||||
"\377\370\325\325\377\372\341\341\377\370\323\323\377\364\263\263\377\365"
|
||||
"\270\270\377\354}}\377\327\036\036\320\307\034\034\062\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\257\030\030"
|
||||
"\007\303\034\034\214\343<<\371\360\225\225\377\366\305\305\377\370\315\315\377"
|
||||
"\370\315\315\377\371\332\332\377\373\344\344\377\375\360\360\377\375\364"
|
||||
"\364\377\373\346\346\377\371\330\330\377\367\312\312\377\367\310\310\377"
|
||||
"\365\272\272\377\357\220\220\377\343<<\371\307\034\034\214\257\030\030\007\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\302\033\033\062\314\035\035\240\342\071\071"
|
||||
"\351\354yy\377\360\225\225\377\363\254\254\377\366\305\305\377\371\330\330"
|
||||
"\377\371\330\330\377\367\307\307\377\363\254\254\377\357\224\224\377\353"
|
||||
"xx\377\343<<\351\320\035\035\240\302\033\033\062\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\275\032\032\033\276\033\033]\311\034"
|
||||
"\034\225\337$$\301\343<<\330\344GG\346\344GG\346\343<<\330\340''\301\313\035"
|
||||
"\035\225\276\033\033]\275\032\032\033\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
|
||||
#if 0
|
||||
};
|
||||
#endif
|
423
source/blood/rsrc/eduke32_icon_48px.c
Normal file
423
source/blood/rsrc/eduke32_icon_48px.c
Normal file
|
@ -0,0 +1,423 @@
|
|||
/* GIMP RGBA C-Source image dump (test.c) */
|
||||
#if 0
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[48 * 48 * 4 + 1];
|
||||
} sdlappicon = {
|
||||
48, 48, 4,
|
||||
#endif
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\037\004\004\001\325\036"
|
||||
"\036(\325\036\036_\325\036\036\222\325\036\036\270\325\036\036\321\325\036\036\343\325"
|
||||
"\036\036\355\325\036\036\355\325\036\036\343\325\036\036\321\325\036\036\270\325\036"
|
||||
"\036\222\325\036\036_\325\036\036(\037\004\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036"
|
||||
"\036\325\036\036s\325\036\036\304\325\036\036\365\343<<\377\350aa\377\355\202\202"
|
||||
"\377\361\242\242\377\366\277\277\377\366\301\301\377\366\277\277\377\362"
|
||||
"\251\251\377\355\202\202\377\350ee\377\345JJ\377\340--\377\325\036\036\365"
|
||||
"\325\036\036\304\325\036\036s\325\036\036\036\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\334\037\037&\325\036\036\222\325\036\036\354\343"
|
||||
"AA\377\360\227\227\377\371\334\334\377\375\364\364\377\376\371\371\377\376"
|
||||
"\371\371\377\375\366\366\377\374\353\353\377\372\341\341\377\371\330\330"
|
||||
"\377\370\315\315\377\365\274\274\377\364\267\267\377\364\267\267\377\363"
|
||||
"\253\253\377\360\235\235\377\352oo\377\341\062\062\377\325\036\036\354\325\036"
|
||||
"\036\222\334\037\037&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\311\034\034\014\325\036\036"
|
||||
"|\325\036\036\354\345NN\377\365\270\270\377\373\350\350\377\375\362\362\377"
|
||||
"\375\362\362\377\375\366\366\377\375\360\360\377\375\362\362\377\375\362"
|
||||
"\362\377\373\350\350\377\371\334\334\377\371\326\326\377\367\312\312\377"
|
||||
"\365\270\270\377\363\262\262\377\363\254\254\377\361\244\244\377\361\242"
|
||||
"\242\377\362\247\247\377\363\262\262\377\361\236\236\377\344GG\377\325\036"
|
||||
"\036\354\325\036\036|\311\034\034\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036\064\325\036\036\305\341\062"
|
||||
"\062\377\360\231\231\377\367\310\310\377\370\325\325\377\371\334\334\377\373"
|
||||
"\350\350\377\374\357\357\377\375\364\364\377\375\366\366\377\375\366\366"
|
||||
"\377\376\367\367\377\375\366\366\377\375\366\366\377\375\364\364\377\374"
|
||||
"\353\353\377\372\341\341\377\370\323\323\377\365\270\270\377\361\236\236"
|
||||
"\377\361\236\236\377\361\244\244\377\363\262\262\377\366\301\301\377\367"
|
||||
"\310\310\377\363\254\254\377\342\067\067\377\325\036\036\305\325\036\036\064\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036Z\325"
|
||||
"\036\036\356\344GG\377\361\236\236\377\363\262\262\377\365\272\272\377\367"
|
||||
"\310\310\377\371\326\326\377\373\350\350\377\375\364\364\377\376\371\371"
|
||||
"\377\371\330\330\377\362\251\251\377\355\206\206\377\351ll\377\347WW\377"
|
||||
"\346OO\377\347XX\377\352oo\377\360\227\227\377\370\325\325\377\375\362\362"
|
||||
"\377\370\325\325\377\365\270\270\377\365\274\274\377\366\301\301\377\367"
|
||||
"\307\307\377\370\323\323\377\372\341\341\377\351ff\377\325\036\036\356\325"
|
||||
"\036\036Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036q\325\036"
|
||||
"\036\374\347XX\377\357\220\220\377\360\225\225\377\361\242\242\377\364\263"
|
||||
"\263\377\370\325\325\377\375\360\360\377\370\323\323\377\356\213\213\377"
|
||||
"\345NN\377\342\067\067\377\342\067\067\377\342\067\067\377\341\062\062\377\340++"
|
||||
"\377\337$$\377\331\037\037\377\320\035\035\377\314\035\035\377\311\034\034\377\337"
|
||||
"\040\040\377\353tt\377\370\315\315\377\374\353\353\377\371\326\326\377\370"
|
||||
"\315\315\377\371\330\330\377\373\346\346\377\374\351\351\377\357\224\224"
|
||||
"\377\325\036\036\374\325\036\036q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036q\320"
|
||||
"\035\035\377\347XX\377\355\206\206\377\355\206\206\377\356\215\215\377\361"
|
||||
"\244\244\377\371\330\330\377\370\321\321\377\347\\\\\377\340''\377\340--"
|
||||
"\377\342\065\065\377\342\067\067\377\342\067\067\377\342\067\067\377\342\065\065\377"
|
||||
"\340++\377\340%%\377\327\036\036\377\320\035\035\377\314\035\035\377\303\034\034"
|
||||
"\377\302\033\033\377\307\034\034\377\322\036\036\377\347XX\377\370\323\323\377"
|
||||
"\374\353\353\377\373\343\343\377\373\350\350\377\373\346\346\377\374\351"
|
||||
"\351\377\363\254\254\377\332\037\037\377\325\036\036q\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036"
|
||||
"Z\325\036\036\374\347WW\377\354yy\377\353xx\377\354\177\177\377\363\254\254"
|
||||
"\377\376\367\367\377\353tt\377\313\035\035\377\327\036\036\377\337\040\040\377"
|
||||
"\340++\377\341\064\064\377\342\067\067\377\342\067\067\377\342\067\067\377\342\065"
|
||||
"\065\377\340--\377\340%%\377\327\036\036\377\320\035\035\377\313\035\035\377\303"
|
||||
"\034\034\377\302\033\033\377\313\035\035\377\325\036\036\377\331\037\037\377\336\037"
|
||||
"\037\377\356\207\207\377\376\371\371\377\374\353\353\377\373\346\346\377\372"
|
||||
"\341\341\377\371\334\334\377\361\236\236\377\325\036\036\374\325\036\036Z\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\327"
|
||||
"\036\036\061\325\036\036\355\345NN\377\354{{\377\352oo\377\353tt\377\364\263\263"
|
||||
"\377\373\350\350\377\343<<\377\275\032\032\377\303\034\034\377\320\035\035\377"
|
||||
"\336\037\037\377\340''\377\341..\377\342\065\065\377\342\067\067\377\342\067\067"
|
||||
"\377\342\065\065\377\340--\377\337$$\377\327\036\036\377\320\035\035\377\311\034"
|
||||
"\034\377\302\033\033\377\303\034\034\377\320\035\035\377\331\037\037\377\332\037\037"
|
||||
"\377\340''\377\340--\377\351ff\377\374\357\357\377\374\353\353\377\371\330"
|
||||
"\330\377\370\315\315\377\367\310\310\377\354}}\377\325\036\036\355\327\036\036"
|
||||
"\061\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\331\037\037\013"
|
||||
"\325\036\036\310\342\071\071\377\356\213\213\377\354\177\177\377\354yy\377\364"
|
||||
"\263\263\377\371\326\326\377\320\035\035\377\262\031\031\377\266\031\031\377\275"
|
||||
"\032\032\377\307\034\034\377\327\036\036\377\337$$\377\340--\377\342\065\065\377"
|
||||
"\342\067\067\377\342\067\067\377\342\065\065\377\340--\377\337$$\377\327\036\036"
|
||||
"\377\314\035\035\377\311\034\034\377\302\033\033\377\311\034\034\377\325\036\036\377"
|
||||
"\331\037\037\377\337\040\040\377\340--\377\341..\377\341..\377\345JJ\377\371"
|
||||
"\334\334\377\373\343\343\377\366\277\277\377\365\270\270\377\366\277\277"
|
||||
"\377\346QQ\377\325\036\036\310\331\037\037\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\325\036\036|\336\037\037\377\360\225\225\377\357\220\220\377"
|
||||
"\356\207\207\377\363\262\262\377\372\341\341\377\303\034\034\377\257\030\030"
|
||||
"\377\260\031\031\377\262\031\031\377\271\032\032\377\340''\377\363\254\254\377"
|
||||
"\340--\377\340))\377\341\062\062\377\342\067\067\377\342\067\067\377\342\067\067"
|
||||
"\377\340--\377\337$$\377\322\036\036\377\314\035\035\377\307\034\034\377\303\034"
|
||||
"\034\377\320\035\035\377\331\037\037\377\353tt\377\345JJ\377\341..\377\341..\377"
|
||||
"\340++\377\340''\377\342\065\065\377\373\344\344\377\370\323\323\377\364\263"
|
||||
"\263\377\364\263\263\377\363\254\254\377\337$$\377\325\036\036|\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\322\036\036\"\325\036\036\356\354\177\177\377\361"
|
||||
"\244\244\377\360\227\227\377\361\242\242\377\375\366\366\377\340''\377\257"
|
||||
"\030\030\377\253\030\030\377\253\030\030\377\260\031\031\377\343<<\377\375\360\360"
|
||||
"\377\370\323\323\377\361\236\236\377\337$$\377\331\037\037\377\275\032\032\377"
|
||||
"\246\027\027\377\223\025\025\377\203\022\022\377\203\022\022\377\214\023\023\377\232"
|
||||
"\026\026\377\250\030\030\377\273\032\032\377\322\036\036\377\342\071\071\377\376\367"
|
||||
"\367\377\375\362\362\377\351jj\377\340--\377\340''\377\336\037\037\377\325"
|
||||
"\036\036\377\343AA\377\375\366\366\377\365\272\272\377\362\251\251\377\361"
|
||||
"\236\236\377\355\202\202\377\325\036\036\356\322\036\036\"\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\325\036\036\222\342\067\067\377\364\267\267\377\362\251\251\377"
|
||||
"\361\244\244\377\370\325\325\377\351ll\377\271\032\032\377\264\031\031\377\262"
|
||||
"\031\031\377\253\030\030\377\346SS\377\376\367\367\377\362\251\251\377\360\225"
|
||||
"\225\377\375\366\366\377\313\035\035\377\177\022\022\377~\021\021\377x\021\021\377"
|
||||
"w\020\020\377u\020\020\377u\020\020\377w\020\020\377x\021\021\377~\021\021\377\177\022"
|
||||
"\022\377\250\030\030\377\363\253\253\377\374\357\357\377\374\357\357\377\376"
|
||||
"\371\371\377\354yy\377\336\037\037\377\327\036\036\377\322\036\036\377\314\035\035"
|
||||
"\377\353tt\377\371\326\326\377\360\231\231\377\360\227\227\377\360\235\235"
|
||||
"\377\342\065\065\377\325\036\036\222\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036\036\325"
|
||||
"\036\036\355\360\227\227\377\366\277\277\377\363\262\262\377\367\310\310\377"
|
||||
"\370\315\315\377\303\034\034\377\276\033\033\377\275\032\032\377\266\031\031\377"
|
||||
"\343<<\377\376\367\367\377\357\220\220\377\354{{\377\351ff\377\356\213\213"
|
||||
"\377\360\227\227\377w\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377"
|
||||
"u\020\020\377u\020\020\377u\020\020\377u\020\020\377w\020\020\377\253\030\030\377\371"
|
||||
"\330\330\377\363\253\253\377\373\344\344\377\371\334\334\377\376\371\371"
|
||||
"\377\347XX\377\322\036\036\377\314\035\035\377\303\034\034\377\302\033\033\377\370"
|
||||
"\315\315\377\364\267\267\377\357\220\220\377\357\220\220\377\354\177\177"
|
||||
"\377\325\036\036\355\325\036\036\036\000\000\000\000\000\000\000\000\325\036\036q\341..\377\367"
|
||||
"\312\312\377\366\301\301\377\365\274\274\377\374\351\351\377\346OO\377\313"
|
||||
"\035\035\377\307\034\034\377\302\033\033\377\340''\377\374\353\353\377\361\244"
|
||||
"\244\377\353tt\377\346QQ\377\346OO\377\365\270\270\377\376\375\375\377\302"
|
||||
"\033\033\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020"
|
||||
"\377u\020\020\377u\020\020\377u\020\020\377\360\231\231\377\370\323\323\377\346"
|
||||
"OO\377\357\220\220\377\366\301\301\377\370\315\315\377\374\357\357\377\341"
|
||||
"..\377\302\033\033\377\276\033\033\377\275\032\032\377\343AA\377\372\341\341\377"
|
||||
"\357\220\220\377\357\224\224\377\360\235\235\377\340))\377\325\036\036q\000\000"
|
||||
"\000\000\221\024\024\003\325\036\036\305\353tt\377\366\301\301\377\365\272\272\377"
|
||||
"\367\312\312\377\370\315\315\377\325\036\036\377\322\036\036\377\320\035\035\377"
|
||||
"\314\035\035\377\364\263\263\377\367\307\307\377\357\220\220\377\350aa\377"
|
||||
"\346OO\377\367\310\310\377\376\375\375\377\376\375\375\377\367\312\312\377"
|
||||
"|\021\021\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020"
|
||||
"\377u\020\020\377\271\032\032\377\376\375\375\377\376\375\375\377\367\310\310"
|
||||
"\377\346OO\377\356\207\207\377\363\262\262\377\370\315\315\377\364\263\263"
|
||||
"\377\276\033\033\377\275\032\032\377\273\032\032\377\273\032\032\377\367\310\310"
|
||||
"\377\363\253\253\377\360\225\225\377\360\231\231\377\350ee\377\325\036\036"
|
||||
"\305\221\024\024\003\327\036\036'\325\036\036\366\363\253\253\377\364\267\267\377"
|
||||
"\365\270\270\377\373\343\343\377\353rr\377\327\036\036\377\327\036\036\377\327"
|
||||
"\036\036\377\345NN\377\374\351\351\377\363\256\256\377\357\220\220\377\341"
|
||||
"\064\064\377\365\270\270\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\343AA\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020"
|
||||
"\020\377u\020\020\377u\020\020\377\364\267\267\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\365\270\270\377\341\064\064\377\356\215\215\377\360\227"
|
||||
"\227\377\373\343\343\377\343<<\377\275\032\032\377\275\032\032\377\276\033\033"
|
||||
"\377\350ee\377\370\323\323\377\357\224\224\377\357\224\224\377\357\220\220"
|
||||
"\377\325\036\036\366\327\036\036'\325\036\036_\341..\377\364\267\267\377\364\263"
|
||||
"\263\377\364\263\263\377\376\371\371\377\337\040\040\377\322\036\036\377\322"
|
||||
"\036\036\377\327\036\036\377\366\277\277\377\370\323\323\377\365\272\272\377"
|
||||
"\351ff\377\356\207\207\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\374\353\353\377\223\025\025\377u\020\020\377"
|
||||
"u\020\020\377u\020\020\377u\020\020\377u\020\020\377\320\035\035\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\356\207"
|
||||
"\207\377\346SS\377\357\224\224\377\365\270\270\377\365\272\272\377\275\032"
|
||||
"\032\377\275\032\032\377\275\032\032\377\314\035\035\377\376\367\367\377\360\231"
|
||||
"\231\377\360\231\231\377\361\242\242\377\340++\377\325\036\036_\325\036\036\222"
|
||||
"\344GG\377\364\267\267\377\363\262\262\377\366\277\277\377\367\307\307\377"
|
||||
"\320\035\035\377\320\035\035\377\320\035\035\377\340--\377\376\371\371\377\365"
|
||||
"\274\274\377\361\242\242\377\343<<\377\372\335\335\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\354\177\177\377\241\027\027\377\346SS\377\352oo\377\340%%\377\212\023\023"
|
||||
"\377\367\312\312\377\376\375\375\377\376\375\375\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\372\335\335\377\343<<\377\355\202\202\377\360"
|
||||
"\225\225\377\376\367\367\377\331\037\037\377\275\032\032\377\276\033\033\377\302"
|
||||
"\033\033\377\366\305\305\377\364\263\263\377\361\236\236\377\363\253\253\377"
|
||||
"\344CC\377\325\036\036\222\325\036\036\272\351ff\377\364\263\263\377\363\256"
|
||||
"\256\377\370\323\323\377\357\220\220\377\320\035\035\377\320\035\035\377\320"
|
||||
"\035\035\377\351ff\377\372\341\341\377\364\263\263\377\352oo\377\354yy\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\354yy\377\350]]\377\360\231\231\377\371"
|
||||
"\330\330\377\350aa\377\302\033\033\377\302\033\033\377\303\034\034\377\357\220"
|
||||
"\220\377\367\312\312\377\361\242\242\377\362\247\247\377\351jj\377\325\036"
|
||||
"\036\272\325\036\036\321\355\202\202\377\365\270\270\377\363\262\262\377\372"
|
||||
"\341\341\377\352mm\377\320\035\035\377\314\035\035\377\314\035\035\377\360\227"
|
||||
"\227\377\370\321\321\377\363\256\256\377\345JJ\377\363\256\256\377\376\375"
|
||||
"\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\363\256\256\377\344EE\377\361\236\236\377\367\310"
|
||||
"\310\377\357\224\224\377\303\034\034\377\303\034\034\377\303\034\034\377\351jj"
|
||||
"\377\371\330\330\377\362\247\247\377\363\253\253\377\356\207\207\377\325"
|
||||
"\036\036\321\325\036\036\343\361\242\242\377\365\270\270\377\364\263\263\377"
|
||||
"\373\350\350\377\347WW\377\320\035\035\377\320\035\035\377\320\035\035\377\365"
|
||||
"\272\272\377\367\307\307\377\363\262\262\377\341..\377\371\326\326\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\376\375\375\377\376\375\375\377\363\256\256\377\244"
|
||||
"\027\027\377u\020\020\377\276\033\033\377\370\323\323\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377"
|
||||
"\376\375\375\377\371\326\326\377\340--\377\362\247\247\377\365\274\274\377"
|
||||
"\366\277\277\377\311\034\034\377\311\034\034\377\311\034\034\377\346QQ\377\373"
|
||||
"\344\344\377\363\253\253\377\363\254\254\377\357\224\224\377\325\036\036\343"
|
||||
"\325\036\036\355\364\263\263\377\366\305\305\377\366\277\277\377\374\357\357"
|
||||
"\377\345NN\377\327\036\036\377\327\036\036\377\327\036\036\377\370\315\315\377"
|
||||
"\367\312\312\377\367\310\310\377\345JJ\377\375\364\364\377\376\375\375\377"
|
||||
"\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375"
|
||||
"\375\377\376\375\375\377\376\367\367\377\223\025\025\377u\020\020\377u\020\020"
|
||||
"\377u\020\020\377\275\032\032\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\375"
|
||||
"\364\364\377\344GG\377\365\274\274\377\365\274\274\377\367\312\312\377\313"
|
||||
"\035\035\377\313\035\035\377\313\035\035\377\344CC\377\374\351\351\377\363\254"
|
||||
"\254\377\363\256\256\377\361\244\244\377\325\036\036\355\325\036\036\355\365"
|
||||
"\270\270\377\367\312\312\377\367\310\310\377\375\360\360\377\346QQ\377\336"
|
||||
"\037\037\377\336\037\037\377\336\037\037\377\363\254\254\377\370\321\321\377\370"
|
||||
"\321\321\377\365\272\272\377\364\267\267\377\364\267\267\377\364\267\267"
|
||||
"\377\364\267\267\377\364\267\267\377\364\267\267\377\372\341\341\377\376"
|
||||
"\375\375\377\367\307\307\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377"
|
||||
"\201\022\022\377\376\375\375\377\376\375\375\377\370\323\323\377\364\267\267"
|
||||
"\377\364\267\267\377\364\267\267\377\364\267\267\377\364\267\267\377\365"
|
||||
"\272\272\377\370\315\315\377\370\315\315\377\361\244\244\377\311\034\034\377"
|
||||
"\311\034\034\377\311\034\034\377\343AA\377\373\350\350\377\363\253\253\377\363"
|
||||
"\254\254\377\361\244\244\377\325\036\036\355\325\036\036\343\365\270\270\377"
|
||||
"\370\323\323\377\370\315\315\377\374\357\357\377\350aa\377\337\040\040\377"
|
||||
"\337$$\377\337$$\377\337$$\377\337$$\377\337$$\377\221\024\024\377w\020\020\377"
|
||||
"u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377\346OO\377\376\375"
|
||||
"\375\377\375\360\360\377\210\023\023\377u\020\020\377u\020\020\377u\020\020\377\253"
|
||||
"\030\030\377\376\375\375\377\376\375\375\377\320\035\035\377u\020\020\377u\020\020"
|
||||
"\377u\020\020\377u\020\020\377w\020\020\377\214\023\023\377\311\034\034\377\311\034"
|
||||
"\034\377\311\034\034\377\311\034\034\377\311\034\034\377\311\034\034\377\346QQ\377"
|
||||
"\373\344\344\377\363\253\253\377\363\253\253\377\360\235\235\377\325\036\036"
|
||||
"\343\325\036\036\321\361\242\242\377\371\330\330\377\370\325\325\377\374\353"
|
||||
"\353\377\354yy\377\337$$\377\340''\377\340''\377\340''\377\340''\377\340"
|
||||
"%%\377\241\027\027\377x\021\021\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377"
|
||||
"u\020\020\377\331\037\037\377\376\375\375\377\376\375\375\377\360\225\225\377"
|
||||
"\210\023\023\377u\020\020\377\233\026\026\377\366\301\301\377\376\375\375\377\376"
|
||||
"\375\375\377\233\026\026\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377x\021"
|
||||
"\021\377\232\026\026\377\313\035\035\377\313\035\035\377\311\034\034\377\311\034\034"
|
||||
"\377\311\034\034\377\311\034\034\377\351jj\377\371\334\334\377\363\253\253\377"
|
||||
"\363\256\256\377\356\207\207\377\325\036\036\321\325\036\036\272\354\177\177"
|
||||
"\377\371\334\334\377\371\330\330\377\373\346\346\377\360\235\235\377\340"
|
||||
"%%\377\340''\377\340%%\377\340%%\377\337\040\040\377\337\040\040\377\262\031\031"
|
||||
"\377~\021\021\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377~\021"
|
||||
"\021\377\367\312\312\377\376\375\375\377\376\375\375\377\376\375\375\377\373"
|
||||
"\344\344\377\376\375\375\377\376\375\375\377\376\375\375\377\360\231\231"
|
||||
"\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377~\021\021\377\251"
|
||||
"\030\030\377\311\034\034\377\311\034\034\377\311\034\034\377\311\034\034\377\311\034"
|
||||
"\034\377\313\035\035\377\357\220\220\377\370\321\321\377\363\254\254\377\363"
|
||||
"\262\262\377\352mm\377\325\036\036\272\325\036\036\222\347XX\377\371\334\334"
|
||||
"\377\371\330\330\377\371\334\334\377\367\312\312\377\337$$\377\337\040\040"
|
||||
"\377\337\040\040\377\336\037\037\377\332\037\037\377\331\037\037\377\303\034\034\377"
|
||||
"\177\022\022\377w\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020"
|
||||
"\020\377\235\026\026\377\367\307\307\377\376\375\375\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\361\236\236\377\212\023\023\377"
|
||||
"u\020\020\377u\020\020\377u\020\020\377u\020\020\377w\020\020\377\177\022\022\377\271"
|
||||
"\032\032\377\307\034\034\377\307\034\034\377\311\034\034\377\311\034\034\377\311\034"
|
||||
"\034\377\311\034\034\377\366\305\305\377\366\277\277\377\363\256\256\377\363"
|
||||
"\262\262\377\345JJ\377\325\036\036\222\325\036\036_\342\065\065\377\371\330\330"
|
||||
"\377\370\325\325\377\370\321\321\377\376\371\371\377\341..\377\336\037\037"
|
||||
"\377\331\037\037\377\327\036\036\377\327\036\036\377\320\035\035\377\313\035\035\377"
|
||||
"\241\027\027\377|\021\021\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020"
|
||||
"\020\377u\020\020\377\351ll\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\376\375\375\377\340%%\377u\020\020\377u\020\020\377u\020"
|
||||
"\020\377u\020\020\377u\020\020\377|\021\021\377\241\027\027\377\302\033\033\377\302"
|
||||
"\033\033\377\303\034\034\377\311\034\034\377\311\034\034\377\311\034\034\377\332\037"
|
||||
"\037\377\376\371\371\377\363\254\254\377\363\254\254\377\363\262\262\377\340"
|
||||
"--\377\325\036\036_\327\036\036'\325\036\036\366\366\277\277\377\367\312\312\377"
|
||||
"\367\307\307\377\373\346\346\377\353rr\377\327\036\036\377\322\036\036\377\320"
|
||||
"\035\035\377\313\035\035\377\302\033\033\377\276\033\033\377\266\031\031\377\177\022"
|
||||
"\022\377w\020\020\377u\020\020\377u\020\020\377u\020\020\377u\020\020\377\253\030\030"
|
||||
"\377\376\367\367\377\376\375\375\377\376\375\375\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\373\344\344\377\210\023\023\377u\020\020\377u\020"
|
||||
"\020\377u\020\020\377w\020\020\377\177\022\022\377\262\031\031\377\275\032\032\377\276"
|
||||
"\033\033\377\302\033\033\377\302\033\033\377\303\034\034\377\303\034\034\377\351ff"
|
||||
"\377\371\334\334\377\362\251\251\377\363\253\253\377\362\247\247\377\325"
|
||||
"\036\036\366\327\036\036'\221\024\024\003\325\036\036\305\354}}\377\367\310\310\377"
|
||||
"\366\301\301\377\370\315\315\377\367\312\312\377\320\035\035\377\311\034\034"
|
||||
"\377\303\034\034\377\302\033\033\377\275\032\032\377\275\032\032\377\276\033\033\377"
|
||||
"\253\030\030\377~\021\021\377w\020\020\377u\020\020\377u\020\020\377w\020\020\377\365"
|
||||
"\272\272\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\376\375\375\377\376\375\375\377\354\177\177\377u\020"
|
||||
"\020\377u\020\020\377w\020\020\377~\021\021\377\253\030\030\377\271\032\032\377\271"
|
||||
"\032\032\377\273\032\032\377\275\032\032\377\276\033\033\377\302\033\033\377\303\034"
|
||||
"\034\377\367\310\310\377\364\267\267\377\361\244\244\377\363\253\253\377\352"
|
||||
"oo\377\325\036\036\305\221\024\024\003\000\000\000\000\325\036\036q\340--\377\367\307\307"
|
||||
"\377\365\270\270\377\363\262\262\377\373\346\346\377\344GG\377\302\033\033"
|
||||
"\377\275\032\032\377\275\032\032\377\275\032\032\377\275\032\032\377\275\032\032\377"
|
||||
"\275\032\032\377\250\030\030\377~\021\021\377w\020\020\377u\020\020\377\343AA\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\271"
|
||||
"\032\032\377w\020\020\377~\021\021\377\250\030\030\377\275\032\032\377\275\032\032\377"
|
||||
"\273\032\032\377\273\032\032\377\271\032\032\377\275\032\032\377\275\032\032\377\343"
|
||||
"AA\377\373\344\344\377\361\236\236\377\361\244\244\377\363\254\254\377\340"
|
||||
"++\377\325\036\036q\000\000\000\000\000\000\000\000\325\036\036\036\325\036\036\355\356\215\215"
|
||||
"\377\363\262\262\377\362\247\247\377\365\272\272\377\370\315\315\377\276"
|
||||
"\033\033\377\275\032\032\377\275\032\032\377\275\032\032\377\275\032\032\377\275\032"
|
||||
"\032\377\273\032\032\377\275\032\032\377\257\030\030\377\177\022\022\377\237\026\026"
|
||||
"\377\374\353\353\377\376\375\375\377\376\375\375\377\376\375\375\377\376"
|
||||
"\375\375\377\376\375\375\377\376\375\375\377\376\375\375\377\376\375\375"
|
||||
"\377\373\346\346\377\370\315\315\377\206\023\023\377\260\031\031\377\276\033\033"
|
||||
"\377\275\032\032\377\276\033\033\377\275\032\032\377\273\032\032\377\271\032\032\377"
|
||||
"\271\032\032\377\275\032\032\377\370\315\315\377\365\270\270\377\360\227\227"
|
||||
"\377\361\242\242\377\356\213\213\377\325\036\036\355\325\036\036\036\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\325\036\036\222\340--\377\362\247\247\377\360\227\227\377\360"
|
||||
"\225\225\377\370\323\323\377\352mm\377\275\032\032\377\275\032\032\377\275\032"
|
||||
"\032\377\273\032\032\377\273\032\032\377\275\032\032\377\302\033\033\377\303\034\034"
|
||||
"\377\276\033\033\377\363\254\254\377\357\224\224\377\354yy\377\363\256\256"
|
||||
"\377\371\326\326\377\375\362\362\377\375\362\362\377\371\326\326\377\363"
|
||||
"\256\256\377\354yy\377\343<<\377\365\270\270\377\355\202\202\377\311\034\034"
|
||||
"\377\303\034\034\377\276\033\033\377\275\032\032\377\275\032\032\377\275\032\032\377"
|
||||
"\275\032\032\377\273\032\032\377\351jj\377\370\315\315\377\356\215\215\377\357"
|
||||
"\224\224\377\361\236\236\377\343<<\377\325\036\036\222\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\322\036\036\"\325\036\036\356\353tt\377\360\227\227\377\360\225"
|
||||
"\225\377\362\251\251\377\375\366\366\377\340--\377\275\032\032\377\273\032\032"
|
||||
"\377\273\032\032\377\275\032\032\377\302\033\033\377\303\034\034\377\311\034\034\377"
|
||||
"\350aa\377\373\346\346\377\361\242\242\377\353tt\377\345NN\377\341\062\062"
|
||||
"\377\336\037\037\377\336\037\037\377\341\062\062\377\345JJ\377\352oo\377\360\231"
|
||||
"\231\377\363\262\262\377\375\366\366\377\341\062\062\377\311\034\034\377\302"
|
||||
"\033\033\377\275\032\032\377\275\032\032\377\275\032\032\377\275\032\032\377\340--"
|
||||
"\377\375\366\366\377\361\236\236\377\356\213\213\377\357\220\220\377\354"
|
||||
"}}\377\325\036\036\356\322\036\036\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\325\036\036|\331\037\037\377\360\227\227\377\360\231\231\377\360\227\227\377"
|
||||
"\366\277\277\377\372\341\341\377\327\036\036\377\273\032\032\377\275\032\032\377"
|
||||
"\276\033\033\377\302\033\033\377\307\034\034\377\332\037\037\377\373\350\350\377"
|
||||
"\370\323\323\377\366\277\277\377\365\270\270\377\365\270\270\377\366\277"
|
||||
"\277\377\367\310\310\377\367\312\312\377\366\277\277\377\364\267\267\377"
|
||||
"\364\263\263\377\364\263\263\377\367\312\312\377\373\346\346\377\356\207"
|
||||
"\207\377\311\034\034\377\303\034\034\377\302\033\033\377\275\032\032\377\275\032\032"
|
||||
"\377\327\036\036\377\373\343\343\377\366\277\277\377\357\220\220\377\357\220"
|
||||
"\220\377\357\224\224\377\340''\377\325\036\036|\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\331\037\037\013\325\036\036\310\342\067\067\377\361\236\236"
|
||||
"\377\357\224\224\377\357\220\220\377\366\305\305\377\371\330\330\377\336"
|
||||
"\037\037\377\276\033\033\377\302\033\033\377\303\034\034\377\311\034\034\377\320\035"
|
||||
"\035\377\346QQ\377\366\277\277\377\376\367\367\377\373\344\344\377\370\325"
|
||||
"\325\377\371\330\330\377\370\325\325\377\371\326\326\377\371\330\330\377"
|
||||
"\370\325\325\377\373\343\343\377\375\366\366\377\365\274\274\377\345JJ\377"
|
||||
"\303\034\034\377\307\034\034\377\311\034\034\377\307\034\034\377\302\033\033\377\336"
|
||||
"\037\037\377\371\330\330\377\367\310\310\377\360\225\225\377\357\224\224\377"
|
||||
"\360\225\225\377\345JJ\377\325\036\036\310\331\037\037\013\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\327\036\036\061\325\036\036\355\347XX\377"
|
||||
"\360\225\225\377\357\220\220\377\357\220\220\377\366\301\301\377\374\351"
|
||||
"\351\377\343AA\377\302\033\033\377\311\034\034\377\314\035\035\377\322\036\036\377"
|
||||
"\327\036\036\377\327\036\036\377\337$$\377\350ee\377\361\236\236\377\363\253"
|
||||
"\253\377\370\321\321\377\370\321\321\377\363\253\253\377\361\236\236\377"
|
||||
"\350ee\377\336\037\037\377\320\035\035\377\314\035\035\377\311\034\034\377\307\034"
|
||||
"\034\377\311\034\034\377\311\034\034\377\343AA\377\374\351\351\377\366\301\301"
|
||||
"\377\360\225\225\377\360\225\225\377\360\231\231\377\352mm\377\325\036\036"
|
||||
"\355\327\036\036\061\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\325\036\036Z\325\036\036\374\352mm\377\360\227\227\377\357\224"
|
||||
"\224\377\360\227\227\377\366\277\277\377\376\371\371\377\354yy\377\313\035"
|
||||
"\035\377\320\035\035\377\322\036\036\377\325\036\036\377\325\036\036\377\322\036\036"
|
||||
"\377\320\035\035\377\325\036\036\377\331\037\037\377\336\037\037\377\336\037\037\377"
|
||||
"\331\037\037\377\322\036\036\377\320\035\035\377\320\035\035\377\320\035\035\377\320"
|
||||
"\035\035\377\313\035\035\377\307\034\034\377\307\034\034\377\354yy\377\376\371\371"
|
||||
"\377\366\277\277\377\360\231\231\377\360\225\225\377\360\231\231\377\354"
|
||||
"\177\177\377\325\036\036\374\325\036\036Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036q\322\036\036"
|
||||
"\377\353rr\377\360\235\235\377\361\236\236\377\361\236\236\377\363\262\262"
|
||||
"\377\371\334\334\377\370\321\321\377\345JJ\377\327\036\036\377\327\036\036\377"
|
||||
"\322\036\036\377\322\036\036\377\320\035\035\377\327\036\036\377\331\037\037\377\336"
|
||||
"\037\037\377\336\037\037\377\332\037\037\377\325\036\036\377\320\035\035\377\320\035"
|
||||
"\035\377\320\035\035\377\320\035\035\377\313\035\035\377\344CC\377\370\315\315\377"
|
||||
"\371\330\330\377\363\262\262\377\361\244\244\377\362\247\247\377\361\236"
|
||||
"\236\377\355\202\202\377\336\037\037\377\325\036\036q\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\325\036\036q\325\036\036\374\351ff\377\361\236\236\377\362\251\251\377"
|
||||
"\362\251\251\377\363\256\256\377\370\315\315\377\374\353\353\377\367\312"
|
||||
"\312\377\354}}\377\341..\377\320\035\035\377\322\036\036\377\327\036\036\377\332"
|
||||
"\037\037\377\336\037\037\377\336\037\037\377\332\037\037\377\327\036\036\377\322\036"
|
||||
"\036\377\320\035\035\377\340++\377\354yy\377\367\312\312\377\373\350\350\377"
|
||||
"\366\305\305\377\362\247\247\377\363\253\253\377\363\253\253\377\362\251"
|
||||
"\251\377\353tt\377\325\036\036\374\325\036\036q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\325\036\036Z\325\036\036\356\345JJ\377\363\254\254\377\364"
|
||||
"\263\263\377\364\263\263\377\365\270\270\377\365\274\274\377\370\315\315"
|
||||
"\377\372\341\341\377\375\364\364\377\370\323\323\377\361\236\236\377\354"
|
||||
"{{\377\353tt\377\346QQ\377\346QQ\377\353tt\377\354{{\377\361\236\236\377"
|
||||
"\370\323\323\377\375\364\364\377\371\334\334\377\366\305\305\377\363\254"
|
||||
"\254\377\362\251\251\377\362\247\247\377\363\262\262\377\363\256\256\377"
|
||||
"\346SS\377\325\036\036\356\325\036\036Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036\064\325\036\036\305\340))\377\357\220\220"
|
||||
"\377\365\274\274\377\366\277\277\377\366\277\277\377\365\274\274\377\365"
|
||||
"\272\272\377\364\263\263\377\366\301\301\377\370\325\325\377\373\343\343"
|
||||
"\377\373\344\344\377\375\360\360\377\375\360\360\377\373\346\346\377\373"
|
||||
"\343\343\377\370\325\325\377\366\301\301\377\364\267\267\377\364\267\267"
|
||||
"\377\363\262\262\377\364\263\263\377\363\262\262\377\363\254\254\377\357"
|
||||
"\220\220\377\341..\377\325\036\036\305\325\036\036\064\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\311\034\034\014\325"
|
||||
"\036\036|\325\036\036\354\343<<\377\361\236\236\377\367\307\307\377\366\277\277"
|
||||
"\377\365\272\272\377\364\267\267\377\364\267\267\377\365\272\272\377\366"
|
||||
"\277\277\377\366\301\301\377\367\312\312\377\370\315\315\377\367\310\310"
|
||||
"\377\366\277\277\377\365\270\270\377\364\267\267\377\364\263\263\377\364"
|
||||
"\263\263\377\365\272\272\377\364\267\267\377\361\236\236\377\344EE\377\325"
|
||||
"\036\036\354\325\036\036|\311\034\034\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\334\037"
|
||||
"\037&\325\036\036\222\325\036\036\354\340))\377\353tt\377\363\256\256\377\366"
|
||||
"\277\277\377\366\301\301\377\366\277\277\377\366\305\305\377\367\307\307"
|
||||
"\377\370\315\315\377\370\321\321\377\370\315\315\377\367\307\307\377\366"
|
||||
"\277\277\377\366\277\277\377\365\270\270\377\363\254\254\377\354{{\377\341"
|
||||
"\064\064\377\325\036\036\354\325\036\036\222\334\037\037&\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\325\036\036\036\325\036\036s\325\036\036"
|
||||
"\304\325\036\036\365\340++\377\345JJ\377\352mm\377\357\220\220\377\363\254"
|
||||
"\254\377\364\267\267\377\364\267\267\377\363\256\256\377\357\220\220\377"
|
||||
"\353rr\377\346OO\377\340--\377\325\036\036\365\325\036\036\304\325\036\036s\325"
|
||||
"\036\036\036\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\037\004\004\001\325\036\036(\325\036\036_\325\036\036"
|
||||
"\222\325\036\036\270\325\036\036\321\325\036\036\343\325\036\036\355\325\036\036\355"
|
||||
"\325\036\036\343\325\036\036\321\325\036\036\270\325\036\036\222\325\036\036_\325\036"
|
||||
"\036(\037\004\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
|
||||
#if 0
|
||||
};
|
||||
#endif
|
BIN
source/blood/rsrc/game.bmp
Normal file
BIN
source/blood/rsrc/game.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
1
source/blood/rsrc/game_icon.c
Normal file
1
source/blood/rsrc/game_icon.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "eduke32_icon.c"
|
BIN
source/blood/rsrc/game_icon.ico
Normal file
BIN
source/blood/rsrc/game_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
80
source/blood/rsrc/gameres.rc
Normal file
80
source/blood/rsrc/gameres.rc
Normal file
|
@ -0,0 +1,80 @@
|
|||
#define NEED_COMMCTRL_H
|
||||
#include "../../build/include/windows_inc.h"
|
||||
#include "../src/startwin.game.h"
|
||||
|
||||
RSRC_ICON ICON "game_icon.ico"
|
||||
RSRC_BMP BITMAP "game.bmp"
|
||||
|
||||
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
|
||||
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
|
||||
CAPTION "Startup"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
|
||||
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
|
||||
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
|
||||
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
|
||||
|
||||
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
|
||||
END
|
||||
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "&Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 6, 50, 8
|
||||
CONTROL "", IDCVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 4, 86, 56
|
||||
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 6, 46, 10
|
||||
//#if defined POLYMER && POLYMER != 0
|
||||
// CONTROL "&Polymer", IDCPOLYMER, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 203, 6, 40, 10
|
||||
//#endif
|
||||
CONTROL "Input devices:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 20, 50, 8
|
||||
CONTROL "", IDCINPUT, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 19, 86, 56
|
||||
CONTROL "&Game:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 35, 100, 8
|
||||
CONTROL "", IDCDATA, "LISTBOX", LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS | LBS_STANDARD | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 45, 226, 43
|
||||
|
||||
CONTROL "Custom game content &directory:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 90, 160, 8
|
||||
CONTROL "", IDCGAMEDIR, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 10, 99, 226, 156
|
||||
CONTROL "&Enable ""autoload"" folder", IDCAUTOLOAD, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 116, 100, 8
|
||||
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
|
||||
END
|
||||
|
||||
#define FILEVER 1,9,9,9
|
||||
#define PRODUCTVER 1,9,9,9
|
||||
#define STRFILEVER "2.0.0devel\0"
|
||||
#define STRPRODUCTVER "2.0.0devel\0"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION FILEVER
|
||||
PRODUCTVERSION PRODUCTVER
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x3L
|
||||
#else
|
||||
FILEFLAGS 0x2L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "NBlood"
|
||||
VALUE "FileVersion", STRFILEVER
|
||||
VALUE "InternalName", "NBlood"
|
||||
VALUE "LegalCopyright", "Copyright © 2018 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
|
||||
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
|
||||
VALUE "OriginalFilename", "nblood.exe"
|
||||
VALUE "ProductName", "NBlood"
|
||||
VALUE "ProductVersion", STRPRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
1 24 "manifest.game.xml"
|
42
source/blood/rsrc/manifest.build.xml
Normal file
42
source/blood/rsrc/manifest.build.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="*"
|
||||
name="EDuke32.Mapster32"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Mapster32 for EDuke32</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
42
source/blood/rsrc/manifest.game.xml
Normal file
42
source/blood/rsrc/manifest.game.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="*"
|
||||
name="NBlood"
|
||||
type="win32"
|
||||
/>
|
||||
<description>NBlood</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
BIN
source/blood/rsrc/source/EDuke32_logo_21_large.psd
Normal file
BIN
source/blood/rsrc/source/EDuke32_logo_21_large.psd
Normal file
Binary file not shown.
BIN
source/blood/rsrc/source/EDuke32_logo_21_large_blue.psd
Normal file
BIN
source/blood/rsrc/source/EDuke32_logo_21_large_blue.psd
Normal file
Binary file not shown.
BIN
source/blood/rsrc/source/EDuke32_logo_21_large_opaque.psd
Normal file
BIN
source/blood/rsrc/source/EDuke32_logo_21_large_opaque.psd
Normal file
Binary file not shown.
BIN
source/blood/rsrc/source/game2.psd
Normal file
BIN
source/blood/rsrc/source/game2.psd
Normal file
Binary file not shown.
BIN
source/blood/rsrc/source/game3.psd
Normal file
BIN
source/blood/rsrc/source/game3.psd
Normal file
Binary file not shown.
BIN
source/blood/rsrc/source/wii-hbc-icon.xcf
Normal file
BIN
source/blood/rsrc/source/wii-hbc-icon.xcf
Normal file
Binary file not shown.
376
source/blood/src/_functio.h
Normal file
376
source/blood/src/_functio.h
Normal file
|
@ -0,0 +1,376 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// _functio.h
|
||||
|
||||
// file created by makehead.exe
|
||||
// these headers contain default key assignments, as well as
|
||||
// default button assignments and game function names
|
||||
// axis defaults are also included
|
||||
|
||||
#include "_control.h"
|
||||
#include "control.h"
|
||||
|
||||
#ifndef function_private_h_
|
||||
#define function_private_h_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// KEEPINSYNC lunatic/con_lang.lua
|
||||
char gamefunctions[NUMGAMEFUNCTIONS][MAXGAMEFUNCLEN] =
|
||||
{
|
||||
"Move_Forward",
|
||||
"Move_Backward",
|
||||
"Turn_Left",
|
||||
"Turn_Right",
|
||||
"Turn_Around",
|
||||
"Strafe",
|
||||
"Strafe_Left",
|
||||
"Strafe_Right",
|
||||
"Jump",
|
||||
"Crouch",
|
||||
"Run",
|
||||
"AutoRun",
|
||||
"Open",
|
||||
"Weapon_Fire",
|
||||
"Weapon_Special_Fire",
|
||||
"Aim_Up",
|
||||
"Aim_Down",
|
||||
"Aim_Center",
|
||||
"Look_Up",
|
||||
"Look_Down",
|
||||
"Tilt_Left",
|
||||
"Tilt_Right",
|
||||
"Weapon_1",
|
||||
"Weapon_2",
|
||||
"Weapon_3",
|
||||
"Weapon_4",
|
||||
"Weapon_5",
|
||||
"Weapon_6",
|
||||
"Weapon_7",
|
||||
"Weapon_8",
|
||||
"Weapon_9",
|
||||
"Weapon_10",
|
||||
"Inventory_Use",
|
||||
"Inventory_Left",
|
||||
"Inventory_Right",
|
||||
"Map_Toggle",
|
||||
"Map_Follow_Mode",
|
||||
"Shrink_Screen",
|
||||
"Enlarge_Screen",
|
||||
"Send_Message",
|
||||
"See_Coop_View",
|
||||
"See_Chase_View",
|
||||
"Mouse_Aiming",
|
||||
"Toggle_Crosshair",
|
||||
"Next_Weapon",
|
||||
"Previous_Weapon",
|
||||
"Holster_Weapon",
|
||||
"Show_Opponents_Weapon",
|
||||
"BeastVision",
|
||||
"CrystalBall",
|
||||
"JumpBoots",
|
||||
"MedKit",
|
||||
"ProximityBombs",
|
||||
"RemoteBombs",
|
||||
"Show_Console",
|
||||
};
|
||||
|
||||
#ifdef __SETUP__
|
||||
|
||||
const char keydefaults[NUMGAMEFUNCTIONS*2][MAXGAMEFUNCLEN] =
|
||||
{
|
||||
"W", "Kpad8",
|
||||
"S", "Kpad2",
|
||||
"Left", "Kpad4",
|
||||
"Right", "KPad6",
|
||||
"BakSpc", "",
|
||||
"LAlt", "RAlt",
|
||||
"A", "",
|
||||
"D", "",
|
||||
"Space", "/",
|
||||
"LCtrl", "",
|
||||
"LShift", "RShift",
|
||||
"CapLck", "",
|
||||
"E", "",
|
||||
"RCtrl", "",
|
||||
"X", "",
|
||||
"Home", "KPad7",
|
||||
"End", "Kpad1",
|
||||
"KPad5", "",
|
||||
"PgUp", "Kpad9",
|
||||
"PgDn", "Kpad3",
|
||||
"Insert", "Kpad0",
|
||||
"Delete", "Kpad.",
|
||||
"1", "",
|
||||
"2", "",
|
||||
"3", "",
|
||||
"4", "",
|
||||
"5", "",
|
||||
"6", "",
|
||||
"7", "",
|
||||
"8", "",
|
||||
"9", "",
|
||||
"0", "",
|
||||
"Enter", "KpdEnt",
|
||||
"[", "",
|
||||
"]", "",
|
||||
"Tab", "",
|
||||
"F", "",
|
||||
"-", "Kpad-",
|
||||
"=", "Kpad+",
|
||||
"T", "",
|
||||
"K", "",
|
||||
"F7", "",
|
||||
"U", "",
|
||||
"I", "",
|
||||
"'", "",
|
||||
";", "",
|
||||
"ScrLck", "",
|
||||
"Y", "",
|
||||
"B", "",
|
||||
"C", "",
|
||||
"J", "",
|
||||
"M", "",
|
||||
"P", "",
|
||||
"R", "",
|
||||
"`", "",
|
||||
};
|
||||
|
||||
const char oldkeydefaults[NUMGAMEFUNCTIONS*2][MAXGAMEFUNCLEN] =
|
||||
{
|
||||
"Up", "Kpad8",
|
||||
"Down", "Kpad2",
|
||||
"Left", "Kpad4",
|
||||
"Right", "KPad6",
|
||||
"BakSpc", "",
|
||||
"LAlt", "RAlt",
|
||||
",", "",
|
||||
".", "",
|
||||
"A", "/",
|
||||
"Z", "",
|
||||
"LShift", "RShift",
|
||||
"CapLck", "",
|
||||
"Space", "",
|
||||
"LCtrl", "RCtrl",
|
||||
"X", "",
|
||||
"Home", "KPad7",
|
||||
"End", "Kpad1",
|
||||
"KPad5", "",
|
||||
"PgUp", "Kpad9",
|
||||
"PgDn", "Kpad3",
|
||||
"Insert", "Kpad0",
|
||||
"Delete", "Kpad.",
|
||||
"1", "",
|
||||
"2", "",
|
||||
"3", "",
|
||||
"4", "",
|
||||
"5", "",
|
||||
"6", "",
|
||||
"7", "",
|
||||
"8", "",
|
||||
"9", "",
|
||||
"0", "",
|
||||
"Enter", "KpdEnt",
|
||||
"[", "",
|
||||
"]", "",
|
||||
"Tab", "",
|
||||
"F", "",
|
||||
"-", "Kpad-",
|
||||
"=", "Kpad+",
|
||||
"T", "",
|
||||
"K", "",
|
||||
"F7", "",
|
||||
"U", "",
|
||||
"I", "",
|
||||
"'", "",
|
||||
";", "",
|
||||
"ScrLck", "",
|
||||
"W", "",
|
||||
"B", "",
|
||||
"C", "",
|
||||
"J", "",
|
||||
"M", "",
|
||||
"P", "",
|
||||
"R", "",
|
||||
"`", "",
|
||||
};
|
||||
|
||||
static const char * mousedefaults[MAXMOUSEBUTTONS] =
|
||||
{
|
||||
"Weapon_Fire",
|
||||
"Weapon_Special_Fire",
|
||||
"",
|
||||
"",
|
||||
"Previous_Weapon",
|
||||
"Next_Weapon",
|
||||
};
|
||||
|
||||
|
||||
static const char * mouseclickeddefaults[MAXMOUSEBUTTONS] =
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
static const char * mouseanalogdefaults[MAXMOUSEAXES] =
|
||||
{
|
||||
"analog_turning",
|
||||
"analog_moving",
|
||||
};
|
||||
|
||||
|
||||
static const char * mousedigitaldefaults[MAXMOUSEDIGITAL] =
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(GEKKO)
|
||||
static const char * joystickdefaults[MAXJOYBUTTONSANDHATS] =
|
||||
{
|
||||
"Open", // A
|
||||
"Fire", // B
|
||||
"Run", // 1
|
||||
"Map", // 2
|
||||
"Previous_Weapon", // -
|
||||
"Next_Weapon", // +
|
||||
"", // Home
|
||||
"Jump", // Z
|
||||
"Crouch", // C
|
||||
"Map", // X
|
||||
"Run", // Y
|
||||
"Jump", // L
|
||||
"Quick_Kick", // R
|
||||
"Crouch", // ZL
|
||||
"Fire", // ZR
|
||||
"Quick_Kick", // D-Pad Up
|
||||
"Inventory_Right", // D-Pad Right
|
||||
"Inventory", // D-Pad Down
|
||||
"Inventory_Left", // D-Pad Left
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickclickeddefaults[MAXJOYBUTTONSANDHATS] =
|
||||
{
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Inventory",
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickanalogdefaults[MAXJOYAXES] =
|
||||
{
|
||||
"analog_strafing",
|
||||
"analog_moving",
|
||||
"analog_turning",
|
||||
"analog_lookingupanddown",
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickdigitaldefaults[MAXJOYDIGITAL] =
|
||||
{
|
||||
};
|
||||
#else
|
||||
static const char * joystickdefaults[MAXJOYBUTTONSANDHATS] =
|
||||
{
|
||||
"Fire",
|
||||
"Strafe",
|
||||
"Run",
|
||||
"Open",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Aim_Down",
|
||||
"Look_Right",
|
||||
"Aim_Up",
|
||||
"Look_Left",
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickclickeddefaults[MAXJOYBUTTONSANDHATS] =
|
||||
{
|
||||
"",
|
||||
"Inventory",
|
||||
"Jump",
|
||||
"Crouch",
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickanalogdefaults[MAXJOYAXES] =
|
||||
{
|
||||
"analog_turning",
|
||||
"analog_moving",
|
||||
"analog_strafing",
|
||||
};
|
||||
|
||||
|
||||
static const char * joystickdigitaldefaults[MAXJOYDIGITAL] =
|
||||
{
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Run",
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
149
source/blood/src/_midi.h
Normal file
149
source/blood/src/_midi.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifndef ___MIDI_H
|
||||
#define ___MIDI_H
|
||||
#include "compat.h"
|
||||
|
||||
#define RELATIVE_BEAT( measure, beat, tick ) \
|
||||
( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
|
||||
|
||||
//Bobby Prince thinks this may be 100
|
||||
//#define GENMIDI_DefaultVolume 100
|
||||
#define GENMIDI_DefaultVolume 90
|
||||
|
||||
#define MAX_FORMAT 1
|
||||
|
||||
#define NUM_MIDI_CHANNELS 16
|
||||
|
||||
#define TIME_PRECISION 16
|
||||
|
||||
#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd"
|
||||
#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk"
|
||||
|
||||
#define MIDI_VOLUME 7
|
||||
#define MIDI_PAN 10
|
||||
#define MIDI_DETUNE 94
|
||||
#define MIDI_RHYTHM_CHANNEL 9
|
||||
#define MIDI_RPN_MSB 100
|
||||
#define MIDI_RPN_LSB 101
|
||||
#define MIDI_DATAENTRY_MSB 6
|
||||
#define MIDI_DATAENTRY_LSB 38
|
||||
#define MIDI_PITCHBEND_MSB 0
|
||||
#define MIDI_PITCHBEND_LSB 0
|
||||
#define MIDI_RUNNING_STATUS 0x80
|
||||
#define MIDI_NOTE_OFF 0x8
|
||||
#define MIDI_NOTE_ON 0x9
|
||||
#define MIDI_POLY_AFTER_TCH 0xA
|
||||
#define MIDI_CONTROL_CHANGE 0xB
|
||||
#define MIDI_PROGRAM_CHANGE 0xC
|
||||
#define MIDI_AFTER_TOUCH 0xD
|
||||
#define MIDI_PITCH_BEND 0xE
|
||||
#define MIDI_SPECIAL 0xF
|
||||
#define MIDI_SYSEX 0xF0
|
||||
#define MIDI_SYSEX_CONTINUE 0xF7
|
||||
#define MIDI_META_EVENT 0xFF
|
||||
#define MIDI_END_OF_TRACK 0x2F
|
||||
#define MIDI_TEMPO_CHANGE 0x51
|
||||
#define MIDI_TIME_SIGNATURE 0x58
|
||||
#define MIDI_RESET_ALL_CONTROLLERS 0x79
|
||||
#define MIDI_ALL_NOTES_OFF 0x7b
|
||||
#define MIDI_MONO_MODE_ON 0x7E
|
||||
#define MIDI_SYSTEM_RESET 0xFF
|
||||
|
||||
#define GET_NEXT_EVENT( track, data ) do { \
|
||||
( data ) = *( track )->pos; \
|
||||
( track )->pos += 1; \
|
||||
} while (0)
|
||||
|
||||
#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf )
|
||||
#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 )
|
||||
|
||||
#define EMIDI_INFINITE -1
|
||||
#define EMIDI_END_LOOP_VALUE 127
|
||||
#define EMIDI_ALL_CARDS 127
|
||||
#define EMIDI_INCLUDE_TRACK 110
|
||||
#define EMIDI_EXCLUDE_TRACK 111
|
||||
#define EMIDI_PROGRAM_CHANGE 112
|
||||
#define EMIDI_VOLUME_CHANGE 113
|
||||
#define EMIDI_CONTEXT_START 114
|
||||
#define EMIDI_CONTEXT_END 115
|
||||
#define EMIDI_LOOP_START 116
|
||||
#define EMIDI_LOOP_END 117
|
||||
#define EMIDI_SONG_LOOP_START 118
|
||||
#define EMIDI_SONG_LOOP_END 119
|
||||
|
||||
#define EMIDI_GeneralMIDI 0
|
||||
#define EMIDI_SoundBlaster 4
|
||||
|
||||
#define EMIDI_AffectsCurrentCard(c, type) (((c) == EMIDI_ALL_CARDS) || ((c) == (type)))
|
||||
#define EMIDI_NUM_CONTEXTS 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *pos;
|
||||
char *loopstart;
|
||||
int16_t loopcount;
|
||||
int16_t RunningStatus;
|
||||
unsigned time;
|
||||
int32_t FPSecondsPerTick;
|
||||
int16_t tick;
|
||||
int16_t beat;
|
||||
int16_t measure;
|
||||
int16_t BeatsPerMeasure;
|
||||
int16_t TicksPerBeat;
|
||||
int16_t TimeBase;
|
||||
int32_t delay;
|
||||
int16_t active;
|
||||
} songcontext;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *start;
|
||||
char *pos;
|
||||
|
||||
int32_t delay;
|
||||
int16_t active;
|
||||
int16_t RunningStatus;
|
||||
|
||||
int16_t currentcontext;
|
||||
songcontext context[EMIDI_NUM_CONTEXTS];
|
||||
|
||||
char EMIDI_IncludeTrack;
|
||||
char EMIDI_ProgramChange;
|
||||
char EMIDI_VolumeChange;
|
||||
} track;
|
||||
|
||||
static int32_t _MIDI_ReadNumber(void *from, size_t size);
|
||||
static int32_t _MIDI_ReadDelta(track *ptr);
|
||||
static void _MIDI_ResetTracks(void);
|
||||
static void _MIDI_AdvanceTick(void);
|
||||
static void _MIDI_MetaEvent(track *Track);
|
||||
static void _MIDI_SysEx(track *Track);
|
||||
static int32_t _MIDI_InterpretControllerInfo(track *Track, int32_t TimeSet, int32_t channel, int32_t c1, int32_t c2);
|
||||
static int32_t _MIDI_SendControlChange(int32_t channel, int32_t c1, int32_t c2);
|
||||
static void _MIDI_SetChannelVolume(int32_t channel, int32_t volume);
|
||||
static void _MIDI_SendChannelVolumes(void);
|
||||
static void _MIDI_InitEMIDI(void);
|
||||
|
||||
#endif
|
7247
source/blood/src/actor.cpp
Normal file
7247
source/blood/src/actor.cpp
Normal file
File diff suppressed because it is too large
Load diff
280
source/blood/src/actor.h
Normal file
280
source/blood/src/actor.h
Normal file
|
@ -0,0 +1,280 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "build.h"
|
||||
#include "common_game.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "fx.h"
|
||||
#include "gameutil.h"
|
||||
|
||||
enum DAMAGE_TYPE {
|
||||
DAMAGE_TYPE_0 = 0,
|
||||
DAMAGE_TYPE_1, // Flame
|
||||
DAMAGE_TYPE_2,
|
||||
DAMAGE_TYPE_3,
|
||||
DAMAGE_TYPE_4,
|
||||
DAMAGE_TYPE_5,
|
||||
DAMAGE_TYPE_6, // Tesla
|
||||
};
|
||||
|
||||
enum VECTOR_TYPE {
|
||||
VECTOR_TYPE_0 = 0,
|
||||
VECTOR_TYPE_1,
|
||||
VECTOR_TYPE_2,
|
||||
VECTOR_TYPE_3,
|
||||
VECTOR_TYPE_4,
|
||||
VECTOR_TYPE_5,
|
||||
VECTOR_TYPE_6,
|
||||
VECTOR_TYPE_7,
|
||||
VECTOR_TYPE_8,
|
||||
VECTOR_TYPE_9,
|
||||
VECTOR_TYPE_10,
|
||||
VECTOR_TYPE_11,
|
||||
VECTOR_TYPE_12,
|
||||
VECTOR_TYPE_13,
|
||||
VECTOR_TYPE_14,
|
||||
VECTOR_TYPE_15,
|
||||
VECTOR_TYPE_16,
|
||||
VECTOR_TYPE_17,
|
||||
VECTOR_TYPE_18,
|
||||
VECTOR_TYPE_19,
|
||||
VECTOR_TYPE_20,
|
||||
VECTOR_TYPE_21,
|
||||
VECTOR_TYPE_22,
|
||||
kVectorMax,
|
||||
};
|
||||
|
||||
struct THINGINFO
|
||||
{
|
||||
short at0; // health
|
||||
short at2; // mass
|
||||
unsigned char at4; // clipdist
|
||||
short at5; // flags
|
||||
int at7; // elasticity
|
||||
int atb; // damage resistance
|
||||
short atf; // cstat
|
||||
short at11; // picnum
|
||||
char at13; // shade
|
||||
unsigned char at14; // pal
|
||||
unsigned char at15; // xrepeat
|
||||
unsigned char at16; // yrepeat
|
||||
int at17[7]; // damage
|
||||
int allowThrow; // By NoOne: indicates if kGDXCustomDude can throw it
|
||||
};
|
||||
|
||||
struct AMMOITEMDATA
|
||||
{
|
||||
short at0;
|
||||
short picnum; // startHealth
|
||||
char shade; // mass
|
||||
char at5;
|
||||
unsigned char xrepeat; // at6
|
||||
unsigned char yrepeat; // at7
|
||||
short at8;
|
||||
unsigned char ata;
|
||||
unsigned char atb;
|
||||
};
|
||||
|
||||
struct WEAPONITEMDATA
|
||||
{
|
||||
short at0;
|
||||
short picnum; // startHealth
|
||||
char shade; // mass
|
||||
char at5;
|
||||
unsigned char xrepeat; // at6
|
||||
unsigned char yrepeat; // at7
|
||||
short at8;
|
||||
short ata;
|
||||
short atc;
|
||||
};
|
||||
|
||||
struct ITEMDATA
|
||||
{
|
||||
short at0; // unused?
|
||||
short picnum; // startHealth
|
||||
char shade; // mass
|
||||
char at5; // unused?
|
||||
unsigned char xrepeat; // at6
|
||||
unsigned char yrepeat; // at7
|
||||
short at8;
|
||||
};
|
||||
|
||||
struct MissileType
|
||||
{
|
||||
short picnum;
|
||||
int at2; // speed
|
||||
int at6; // angle
|
||||
unsigned char ata; // xrepeat
|
||||
unsigned char atb; // yrepeat
|
||||
char atc; // shade
|
||||
unsigned char atd; // clipdist
|
||||
int fireSound[2]; // By NoOne: predefined fire sounds. used by kGDXCustomDude, but can be used for something else.
|
||||
};
|
||||
|
||||
struct EXPLOSION
|
||||
{
|
||||
unsigned char at0;
|
||||
char at1; // dmg
|
||||
char at2; // dmg rnd
|
||||
int at3; // radius
|
||||
int at7;
|
||||
int atb;
|
||||
int atf;
|
||||
int at13;
|
||||
int at17;
|
||||
};
|
||||
|
||||
struct VECTORDATA_at1d {
|
||||
FX_ID at0;
|
||||
FX_ID at1;
|
||||
FX_ID at2;
|
||||
int at3;
|
||||
};
|
||||
|
||||
struct VECTORDATA {
|
||||
DAMAGE_TYPE at0;
|
||||
int at1; // damage
|
||||
int at5;
|
||||
int maxDist; // range
|
||||
int atd;
|
||||
int at11; // burn
|
||||
int at15; // blood splats
|
||||
int at19; // blood splat chance
|
||||
VECTORDATA_at1d at1d[15];
|
||||
int fireSound[2]; // By NoOne: predefined fire sounds. used by kGDXCustomDude, but can be used for something else.
|
||||
};
|
||||
|
||||
struct SPRITEHIT {
|
||||
int hit, ceilhit, florhit;
|
||||
};
|
||||
|
||||
extern AMMOITEMDATA gAmmoItemData[];
|
||||
extern WEAPONITEMDATA gWeaponItemData[];
|
||||
extern ITEMDATA gItemData[];
|
||||
extern MissileType missileInfo[];
|
||||
extern EXPLOSION explodeInfo[];
|
||||
extern THINGINFO thingInfo[];
|
||||
extern VECTORDATA gVectorData[];
|
||||
|
||||
extern SPRITEHIT gSpriteHit[];
|
||||
|
||||
extern int gDudeDrag;
|
||||
extern short gAffectedSectors[kMaxSectors];
|
||||
extern short gAffectedXWalls[kMaxXWalls];
|
||||
|
||||
inline void GetSpriteExtents(spritetype *pSprite, int *top, int *bottom)
|
||||
{
|
||||
*top = *bottom = pSprite->z;
|
||||
if ((pSprite->cstat & 0x30) != 0x20)
|
||||
{
|
||||
int height = tilesiz[pSprite->picnum].y;
|
||||
int center = height / 2 + picanm[pSprite->picnum].yofs;
|
||||
*top -= (pSprite->yrepeat << 2)*center;
|
||||
*bottom += (pSprite->yrepeat << 2)*(height - center);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool IsPlayerSprite(spritetype *pSprite)
|
||||
{
|
||||
if (pSprite->type >= kDudePlayer1 && pSprite->type <= kDudePlayer8)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool IsDudeSprite(spritetype *pSprite)
|
||||
{
|
||||
if (pSprite->type >= kDudeBase && pSprite->type < kDudeMax)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void actBurnSprite(int nSource, XSPRITE *pXSprite, int nTime)
|
||||
{
|
||||
pXSprite->burnTime = ClipHigh(pXSprite->burnTime + nTime, sprite[pXSprite->reference].statnum == 6 ? 2400 : 1200);
|
||||
pXSprite->burnSource = nSource;
|
||||
}
|
||||
|
||||
bool IsItemSprite(spritetype *pSprite);
|
||||
bool IsWeaponSprite(spritetype *pSprite);
|
||||
bool IsAmmoSprite(spritetype *pSprite);
|
||||
bool IsUnderwaterSector(int nSector);
|
||||
int actSpriteOwnerToSpriteId(spritetype *pSprite);
|
||||
void actPropagateSpriteOwner(spritetype *pTarget, spritetype *pSource);
|
||||
int actSpriteIdToOwnerId(int nSprite);
|
||||
int actOwnerIdToSpriteId(int nSprite);
|
||||
bool actTypeInSector(int nSector, int nType);
|
||||
void actAllocateSpares(void);
|
||||
void actInit(void);
|
||||
void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6);
|
||||
int actWallBounceVector(int *x, int *y, int nWall, int a4);
|
||||
int actFloorBounceVector(int *x, int *y, int *z, int nSector, int a5);
|
||||
void sub_2A620(int nSprite, int x, int y, int z, int nSector, int nDist, int a7, int a8, DAMAGE_TYPE a9, int a10, int a11, int a12, int a13);
|
||||
void sub_2AA94(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
spritetype *actSpawnFloor(spritetype *pSprite);
|
||||
spritetype *actDropAmmo(spritetype *pSprite, int nType);
|
||||
spritetype *actDropWeapon(spritetype *pSprite, int nType);
|
||||
spritetype *actDropItem(spritetype *pSprite, int nType);
|
||||
spritetype *actDropKey(spritetype *pSprite, int nType);
|
||||
spritetype *actDropFlag(spritetype *pSprite, int nType);
|
||||
spritetype *actDropObject(spritetype *pSprite, int nType);
|
||||
bool actHealDude(XSPRITE *pXDude, int a2, int a3);
|
||||
void actKillDude(int a1, spritetype *pSprite, DAMAGE_TYPE a3, int a4);
|
||||
int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE a3, int a4);
|
||||
void actHitcodeToData(int a1, HITINFO *pHitInfo, int *a3, spritetype **a4, XSPRITE **a5, int *a6, walltype **a7, XWALL **a8, int *a9, sectortype **a10, XSECTOR **a11);
|
||||
void actImpactMissile(spritetype *pMissile, int a2);
|
||||
void actKickObject(spritetype *pSprite1, spritetype *pSprite2);
|
||||
void actTouchFloor(spritetype *pSprite, int nSector);
|
||||
void ProcessTouchObjects(spritetype *pSprite, int nXSprite);
|
||||
void actAirDrag(spritetype *pSprite, int a2);
|
||||
int MoveThing(spritetype *pSprite);
|
||||
void MoveDude(spritetype *pSprite);
|
||||
int MoveMissile(spritetype *pSprite);
|
||||
void actExplodeSprite(spritetype *pSprite);
|
||||
void actActivateGibObject(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
bool IsUnderWater(spritetype *pSprite);
|
||||
void actProcessSprites(void);
|
||||
spritetype * actSpawnSprite(int nSector, int x, int y, int z, int nStat, char a6);
|
||||
spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4);
|
||||
spritetype * actSpawnSprite(spritetype *pSource, int nStat);
|
||||
spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType);
|
||||
spritetype * actFireThing(spritetype *pSprite, int a2, int a3, int a4, int thingType, int a6);
|
||||
spritetype* actFireMissile(spritetype *pSprite, int a2, int a3, int a4, int a5, int a6, int nType);
|
||||
int actGetRespawnTime(spritetype *pSprite);
|
||||
bool actCheckRespawn(spritetype *pSprite);
|
||||
bool actCanSplatWall(int nWall);
|
||||
void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, VECTOR_TYPE vectorType);
|
||||
void actPostSprite(int nSprite, int nStatus);
|
||||
void actPostProcess(void);
|
||||
void MakeSplash(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem);
|
||||
spritetype* spawnRandomDude(spritetype* pSprite);
|
||||
int GetDataVal(spritetype* pSprite, int data);
|
||||
int my_random(int a, int b);
|
||||
int GetRandDataVal(int *rData, spritetype* pSprite);
|
||||
bool sfxPlayMissileSound(spritetype* pSprite, int missileId);
|
||||
bool sfxPlayVectorSound(spritetype* pSprite, int vectorId);
|
||||
spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist);
|
||||
int getDudeMassBySpriteSize(spritetype* pSprite);
|
||||
bool ceilIsTooLow(spritetype* pSprite);
|
1802
source/blood/src/ai.cpp
Normal file
1802
source/blood/src/ai.cpp
Normal file
File diff suppressed because it is too large
Load diff
105
source/blood/src/ai.h
Normal file
105
source/blood/src/ai.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "compat.h"
|
||||
#include "common_game.h"
|
||||
#include "actor.h"
|
||||
#include "db.h"
|
||||
|
||||
struct AISTATE {
|
||||
int stateType; // By NoOne: current type of state. Basically required for kGDXDudeTargetChanger, but can be used for something else.
|
||||
int at0; // seq
|
||||
int at4; // seq callback
|
||||
int at8;
|
||||
void(*atc)(spritetype *, XSPRITE *);
|
||||
void(*at10)(spritetype *, XSPRITE *);
|
||||
void(*at14)(spritetype *, XSPRITE *);
|
||||
AISTATE *at18; // next state ?
|
||||
};
|
||||
extern AISTATE aiState[];
|
||||
|
||||
enum AI_SFX_PRIORITY {
|
||||
AI_SFX_PRIORITY_0 = 0,
|
||||
AI_SFX_PRIORITY_1,
|
||||
AI_SFX_PRIORITY_2,
|
||||
};
|
||||
|
||||
|
||||
struct DUDEEXTRA_at6_u1
|
||||
{
|
||||
int at0;
|
||||
int at4;
|
||||
char at8;
|
||||
};
|
||||
|
||||
struct DUDEEXTRA_at6_u2
|
||||
{
|
||||
int at0;
|
||||
char at4;
|
||||
};
|
||||
|
||||
struct DUDEEXTRA
|
||||
{
|
||||
int at0;
|
||||
char at4;
|
||||
AI_SFX_PRIORITY at5;
|
||||
union
|
||||
{
|
||||
DUDEEXTRA_at6_u1 u1;
|
||||
DUDEEXTRA_at6_u2 u2;
|
||||
} at6;
|
||||
//DUDEEXTRA_at6 at6;
|
||||
};
|
||||
|
||||
struct TARGETTRACK {
|
||||
int at0;
|
||||
int at4;
|
||||
int at8; // view angle
|
||||
int atc;
|
||||
int at10; // Move predict
|
||||
};
|
||||
|
||||
extern int dword_138BB0[5];
|
||||
extern DUDEEXTRA gDudeExtra[];
|
||||
extern int gDudeSlope[];
|
||||
|
||||
bool sub_5BDA8(spritetype *pSprite, int nSeq);
|
||||
void aiPlay3DSound(spritetype *pSprite, int a2, AI_SFX_PRIORITY a3, int a4);
|
||||
void aiNewState(spritetype *pSprite, XSPRITE *pXSprite, AISTATE *pAIState);
|
||||
void aiChooseDirection(spritetype *pSprite, XSPRITE *pXSprite, int a3);
|
||||
void aiMoveForward(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void aiMoveTurn(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void aiMoveDodge(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void aiSetTarget(XSPRITE *pXSprite, int x, int y, int z);
|
||||
void aiSetTarget(XSPRITE *pXSprite, int nTarget);
|
||||
int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_TYPE nDmgType, int nDamage);
|
||||
void aiThinkTarget(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void sub_5F15C(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
void aiProcessDudes(void);
|
||||
void aiInit(void);
|
||||
void aiInitSprite(spritetype *pSprite);
|
||||
|
||||
// By NoOne: this function required for kGDXDudeTargetChanger
|
||||
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite);
|
437
source/blood/src/aibat.cpp
Normal file
437
source/blood/src/aibat.cpp
Normal file
|
@ -0,0 +1,437 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aibat.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BiteSeqCallback(int, int);
|
||||
static void thinkTarget(spritetype *, XSPRITE *);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkPonder(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeUp(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeDown(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void MoveForward(spritetype *, XSPRITE *);
|
||||
static void MoveSwoop(spritetype *, XSPRITE *);
|
||||
static void MoveFly(spritetype *, XSPRITE *);
|
||||
static void MoveToCeil(spritetype *, XSPRITE *);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(BiteSeqCallback);
|
||||
|
||||
AISTATE batIdle = {kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE batFlyIdle = {kAiStateIdle, 6, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE batChase = {kAiStateChase, 6, -1, 0, NULL, MoveForward, thinkChase, &batFlyIdle };
|
||||
AISTATE batPonder = {kAiStateOther, 6, -1, 0, NULL, NULL, thinkPonder, NULL };
|
||||
AISTATE batGoto = {kAiStateMove, 6, -1, 600, NULL, MoveForward, thinkGoto, &batFlyIdle };
|
||||
AISTATE batBite = {kAiStateChase, 7, nBiteClient, 60, NULL, NULL, NULL, &batPonder };
|
||||
AISTATE batRecoil = {kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &batChase };
|
||||
AISTATE batSearch = {kAiStateSearch, 6, -1, 120, NULL, MoveForward, thinkSearch, &batFlyIdle };
|
||||
AISTATE batSwoop = {kAiStateOther, 6, -1, 60, NULL, MoveSwoop, thinkChase, &batChase };
|
||||
AISTATE batFly = { kAiStateMove, 6, -1, 0, NULL, MoveFly, thinkChase, &batChase };
|
||||
AISTATE batTurn = {kAiStateMove, 6, -1, 60, NULL, aiMoveTurn, NULL, &batChase };
|
||||
AISTATE batHide = {kAiStateOther, 6, -1, 0, NULL, MoveToCeil, MoveForward, NULL };
|
||||
AISTATE batDodgeUp = {kAiStateMove, 6, -1, 120, NULL, MoveDodgeUp, 0, &batChase };
|
||||
AISTATE batDodgeUpRight = {kAiStateMove, 6, -1, 90, NULL, MoveDodgeUp, 0, &batChase };
|
||||
AISTATE batDodgeUpLeft = {kAiStateMove, 6, -1, 90, NULL, MoveDodgeUp, 0, &batChase };
|
||||
AISTATE batDodgeDown = {kAiStateMove, 6, -1, 120, NULL, MoveDodgeDown, 0, &batChase };
|
||||
AISTATE batDodgeDownRight = {kAiStateMove, 6, -1, 90, NULL, MoveDodgeDown, 0, &batChase };
|
||||
AISTATE batDodgeDownLeft = {kAiStateMove, 6, -1, 90, NULL, MoveDodgeDown, 0, &batChase };
|
||||
|
||||
static void BiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
spritetype *pSprite = &sprite[pXSprite->reference];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int dx = Cos(pSprite->ang) >> 16;
|
||||
int dy = Sin(pSprite->ang) >> 16;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2;
|
||||
int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2;
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, height2-height, VECTOR_TYPE_6);
|
||||
}
|
||||
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
if (pDudeExtraE->at8 && pDudeExtraE->at4 < 10)
|
||||
pDudeExtraE->at4++;
|
||||
else if (pDudeExtraE->at4 >= 10 && pDudeExtraE->at8)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
aiNewState(pSprite, pXSprite, &batTurn);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
thinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &batSearch);
|
||||
thinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkPonder(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
int height2 = (dudeInfo[pTarget->type-kDudeBase].eyeHeight*pTarget->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (height2-height < 0x3000 && nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeUp);
|
||||
else if (height2-height > 0x5000 && nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeDown);
|
||||
else if (height2-height < 0x2000 && nDist < 0x200 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeUp);
|
||||
else if (height2-height > 0x6000 && nDist < 0x1400 && nDist > 0x800 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeDown);
|
||||
else if (height2-height < 0x2000 && nDist < 0x1400 && nDist > 0x800 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeUp);
|
||||
else if (height2-height < 0x2000 && klabs(nDeltaAngle) < 85 && nDist > 0x1400)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeUp);
|
||||
else if (height2-height > 0x4000)
|
||||
aiNewState(pSprite, pXSprite, &batDodgeDown);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &batDodgeUp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
aiNewState(pSprite, pXSprite, &batGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void MoveDodgeUp(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x52aaa;
|
||||
}
|
||||
|
||||
static void MoveDodgeDown(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
if (pXSprite->dodgeDir == 0)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x44444;
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
// Should be dudeInfo[pTarget->type-kDudeBase]
|
||||
int height2 = (pDudeInfo->eyeHeight*pTarget->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int floorZ = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
if (height2-height < 0x2000 && nDist < 0x200 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batBite);
|
||||
else if ((height2-height > 0x5000 || floorZ-bottom > 0x5000) && nDist < 0x1400 && nDist > 0x800 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batSwoop);
|
||||
else if ((height2-height < 0x3000 || floorZ-bottom < 0x3000) && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &batFly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &batFly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pXSprite->target = -1;
|
||||
aiNewState(pSprite, pXSprite, &batHide);
|
||||
}
|
||||
|
||||
static void MoveForward(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if ((unsigned int)Random(64) < 32 && nDist <= 0x200)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void MoveSwoop(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x200)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x44444;
|
||||
}
|
||||
|
||||
static void MoveFly(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x200)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x2d555;
|
||||
}
|
||||
|
||||
void MoveToCeil(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = pSprite->z;
|
||||
int nSector = pSprite->sectnum;
|
||||
if (z - pXSprite->targetZ < 0x1000)
|
||||
{
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
pDudeExtraE->at8 = 0;
|
||||
pSprite->hitag = 0;
|
||||
aiNewState(pSprite, pXSprite, &batIdle);
|
||||
}
|
||||
else
|
||||
aiSetTarget(pXSprite, x, y, sector[nSector].ceilingz);
|
||||
}
|
43
source/blood/src/aibat.h
Normal file
43
source/blood/src/aibat.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE batIdle;
|
||||
extern AISTATE batFlyIdle;
|
||||
extern AISTATE batChase;
|
||||
extern AISTATE batPonder;
|
||||
extern AISTATE batGoto;
|
||||
extern AISTATE batBite;
|
||||
extern AISTATE batRecoil;
|
||||
extern AISTATE batSearch;
|
||||
extern AISTATE batSwoop;
|
||||
extern AISTATE batFly;
|
||||
extern AISTATE batTurn;
|
||||
extern AISTATE batHide;
|
||||
extern AISTATE batDodgeUp;
|
||||
extern AISTATE batDodgeUpRight;
|
||||
extern AISTATE batDodgeUpLeft;
|
||||
extern AISTATE batDodgeDown;
|
||||
extern AISTATE batDodgeDownRight;
|
||||
extern AISTATE batDodgeDownLeft;
|
581
source/blood/src/aibeast.cpp
Normal file
581
source/blood/src/aibeast.cpp
Normal file
|
@ -0,0 +1,581 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aibeast.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void SlashSeqCallback(int, int);
|
||||
static void StompSeqCallback(int, int);
|
||||
static void MorphToBeast(spritetype *, XSPRITE *);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void thinkSwimGoto(spritetype *, XSPRITE *);
|
||||
static void thinkSwimChase(spritetype *, XSPRITE *);
|
||||
static void MoveForward(spritetype *, XSPRITE *);
|
||||
static void sub_628A0(spritetype *, XSPRITE *);
|
||||
static void sub_62AE0(spritetype *, XSPRITE *);
|
||||
static void sub_62D7C(spritetype *, XSPRITE *);
|
||||
|
||||
static int nSlashClient = seqRegisterClient(SlashSeqCallback);
|
||||
static int nStompClient = seqRegisterClient(StompSeqCallback);
|
||||
|
||||
AISTATE beastIdle = {kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE beastChase = {kAiStateChase, 8, -1, 0, NULL, MoveForward, thinkChase, NULL };
|
||||
AISTATE beastDodge = { kAiStateMove, 8, -1, 60, NULL, aiMoveDodge, NULL, &beastChase };
|
||||
AISTATE beastGoto = { kAiStateMove, 8, -1, 600, NULL, MoveForward, thinkGoto, &beastIdle };
|
||||
AISTATE beastSlash = { kAiStateChase, 6, nSlashClient, 120, NULL, NULL, NULL, &beastChase };
|
||||
AISTATE beastStomp = { kAiStateChase, 7, nStompClient, 120, NULL, NULL, NULL, &beastChase };
|
||||
AISTATE beastSearch = { kAiStateSearch, 8, -1, 120, NULL, MoveForward, thinkSearch, &beastIdle };
|
||||
AISTATE beastRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &beastDodge };
|
||||
AISTATE beastTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &beastDodge };
|
||||
AISTATE beastSwimIdle = {kAiStateIdle, 9, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE beastSwimChase = { kAiStateChase, 9, -1, 0, NULL, sub_628A0, thinkSwimChase, NULL };
|
||||
AISTATE beastSwimDodge = { kAiStateMove, 9, -1, 90, NULL, aiMoveDodge, NULL, &beastSwimChase };
|
||||
AISTATE beastSwimGoto = { kAiStateMove, 9, -1, 600, NULL, MoveForward, thinkSwimGoto, &beastSwimIdle };
|
||||
AISTATE beastSwimSearch = { kAiStateSearch, 9, -1, 120, NULL, MoveForward, thinkSearch, &beastSwimIdle };
|
||||
AISTATE beastSwimSlash = { kAiStateChase, 9, nSlashClient, 0, NULL, NULL, thinkSwimChase, &beastSwimChase };
|
||||
AISTATE beastSwimRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &beastSwimDodge };
|
||||
AISTATE beastMorphToBeast = { kAiStateOther, -1, -1, 0, MorphToBeast, NULL, NULL, &beastIdle };
|
||||
AISTATE beastMorphFromCultist = { kAiStateOther, 2576, -1, 0, NULL, NULL, NULL, &beastMorphToBeast };
|
||||
AISTATE beast138FB4 = { kAiStateOther, 9, -1, 120, NULL, sub_62AE0, thinkSwimChase, &beastSwimChase };
|
||||
AISTATE beast138FD0 = { kAiStateOther, 9, -1, 0, NULL, sub_62D7C, thinkSwimChase, &beastSwimChase };
|
||||
AISTATE beast138FEC = { kAiStateOther, 9, -1, 120, NULL, aiMoveTurn, NULL, &beastSwimChase };
|
||||
|
||||
static void SlashSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
// Correct ?
|
||||
int dz = pSprite->z-pTarget->z;
|
||||
dx += Random3(4000-700*gGameOptions.nDifficulty);
|
||||
dy += Random3(4000-700*gGameOptions.nDifficulty);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_13);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_13);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_13);
|
||||
sfxPlay3DSound(pSprite, 9012+Random(2), -1, 0);
|
||||
}
|
||||
|
||||
static void StompSeqCallback(int, int nXSprite)
|
||||
{
|
||||
char vb8[(kMaxSectors+7)>>3];
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = pSprite->z;
|
||||
int vc = 400;
|
||||
int nSector = pSprite->sectnum;
|
||||
int v1c = 5+2*gGameOptions.nDifficulty;
|
||||
int v10 = 25+30*gGameOptions.nDifficulty;
|
||||
gAffectedSectors[0] = -1;
|
||||
gAffectedXWalls[0] = -1;
|
||||
GetClosestSpriteSectors(nSector, x, y, vc, gAffectedSectors, vb8, gAffectedXWalls);
|
||||
char v4 = 0;
|
||||
int v34 = -1;
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
actHitcodeToData(hit, &gHitInfo, &v34, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (hit == 3 && v34 >= 0)
|
||||
{
|
||||
if (sprite[v34].statnum == 6)
|
||||
v4 = 0;
|
||||
}
|
||||
vc <<= 4;
|
||||
for (int nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
if (nSprite != nSprite2 || v4)
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite2->extra > 0 && pSprite2->extra < kMaxXSprites)
|
||||
{
|
||||
if (pSprite2->type == 251)
|
||||
continue;
|
||||
if (pSprite2->hitag&32)
|
||||
continue;
|
||||
if (TestBitString(vb8, pSprite2->sectnum) && CheckProximity(pSprite2, x, y, z, nSector, vc))
|
||||
{
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (klabs(bottom-sector[nSector].floorz) == 0)
|
||||
{
|
||||
int dx = klabs(pSprite->x-pSprite2->x);
|
||||
int dy = klabs(pSprite->y-pSprite2->y);
|
||||
int nDist2 = ksqrt(dx*dx + dy*dy);
|
||||
if (nDist2 <= vc)
|
||||
{
|
||||
int nDamage;
|
||||
if (!nDist2)
|
||||
nDamage = v1c + v10;
|
||||
else
|
||||
nDamage = v1c + ((vc-nDist2)*v10)/vc;
|
||||
if (IsPlayerSprite(pSprite2))
|
||||
gPlayer[pSprite2->type-kDudePlayer1].at37f += nDamage*4;
|
||||
actDamageSprite(nSprite, pSprite2, DAMAGE_TYPE_0, nDamage<<4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int nSprite2 = headspritestat[4]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite2->hitag&32)
|
||||
continue;
|
||||
if (TestBitString(vb8, pSprite2->sectnum) && CheckProximity(pSprite2, x, y, z, nSector, vc))
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[pSprite2->extra];
|
||||
if (pXSprite->locked)
|
||||
continue;
|
||||
int dx = klabs(pSprite->x-pSprite2->x);
|
||||
int dy = klabs(pSprite->y-pSprite2->y);
|
||||
int nDist2 = ksqrt(dx*dx + dy*dy);
|
||||
if (nDist2 <= vc)
|
||||
{
|
||||
int nDamage;
|
||||
if (!nDist2)
|
||||
nDamage = v1c + v10;
|
||||
else
|
||||
nDamage = v1c + ((vc-nDist2)*v10)/vc;
|
||||
if (IsPlayerSprite(pSprite2))
|
||||
gPlayer[pSprite2->type-kDudePlayer1].at37f += nDamage*4;
|
||||
actDamageSprite(nSprite, pSprite2, DAMAGE_TYPE_0, nDamage<<4);
|
||||
}
|
||||
}
|
||||
}
|
||||
sfxPlay3DSound(pSprite, 9015+Random(2), -1, 0);
|
||||
}
|
||||
|
||||
static void MorphToBeast(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
actHealDude(pXSprite, dudeInfo[51].startHealth, dudeInfo[51].startHealth);
|
||||
pSprite->type = 251;
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSearch);
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int nXSprite = sprite[pXSprite->reference].extra;
|
||||
gDudeSlope[nXSprite] = divscale(pTarget->z-pSprite->z, nDist, 10);
|
||||
if (nDist < 0x1400 && nDist > 0xa00 && klabs(nDeltaAngle) < 85 && (pTarget->hitag&2)
|
||||
&& IsPlayerSprite(pTarget) && Chance(0x8000))
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
if (pXTarget->health > gPlayerTemplate[0].startHealth/2)
|
||||
{
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (!pXSector || !pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastStomp);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
{
|
||||
if (!pXSector || !pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastStomp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimDodge);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!pXSector || !pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastStomp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nDist < 921 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSlash);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSlash);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSlash);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSlash);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimDodge);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSlash);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastSlash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimGoto);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beastGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void thinkSwimGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkSwimChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &beastSwimGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = pDudeInfo->eyeHeight+pSprite->z;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int UNUSED(floorZ) = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &beastSwimSlash);
|
||||
else
|
||||
{
|
||||
aiPlay3DSound(pSprite, 9009+Random(2), AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &beast138FD0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &beast138FD0);
|
||||
return;
|
||||
}
|
||||
aiNewState(pSprite, pXSprite, &beastSwimGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void MoveForward(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= 0x400 && Random(64) < 32)
|
||||
return;
|
||||
xvel[nSprite] += mulscale30(pDudeInfo->frontSpeed, Cos(pSprite->ang));
|
||||
yvel[nSprite] += mulscale30(pDudeInfo->frontSpeed, Sin(pSprite->ang));
|
||||
}
|
||||
|
||||
static void sub_628A0(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Random(64) < 32 && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>2;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void sub_62AE0(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = z2 - z;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -dz;
|
||||
}
|
||||
|
||||
static void sub_62D7C(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = (z2 - z)<<3;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = dz;
|
||||
}
|
46
source/blood/src/aibeast.h
Normal file
46
source/blood/src/aibeast.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE beastIdle;
|
||||
extern AISTATE beastChase;
|
||||
extern AISTATE beastDodge;
|
||||
extern AISTATE beastGoto;
|
||||
extern AISTATE beastSlash;
|
||||
extern AISTATE beastStomp;
|
||||
extern AISTATE beastSearch;
|
||||
extern AISTATE beastRecoil;
|
||||
extern AISTATE beastTeslaRecoil;
|
||||
extern AISTATE beastSwimIdle;
|
||||
extern AISTATE beastSwimChase;
|
||||
extern AISTATE beastSwimDodge;
|
||||
extern AISTATE beastSwimGoto;
|
||||
extern AISTATE beastSwimSearch;
|
||||
extern AISTATE beastSwimSlash;
|
||||
extern AISTATE beastSwimRecoil;
|
||||
extern AISTATE beastMorphToBeast;
|
||||
extern AISTATE beastMorphFromCultist;
|
||||
extern AISTATE beast138FB4;
|
||||
extern AISTATE beast138FD0;
|
||||
extern AISTATE beast138FEC;
|
442
source/blood/src/aiboneel.cpp
Normal file
442
source/blood/src/aiboneel.cpp
Normal file
|
@ -0,0 +1,442 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aiboneel.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BiteSeqCallback(int, int);
|
||||
static void thinkTarget(spritetype *, XSPRITE *);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkPonder(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeUp(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeDown(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void MoveForward(spritetype *, XSPRITE *);
|
||||
static void MoveSwoop(spritetype *, XSPRITE *);
|
||||
static void MoveAscend(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void MoveToCeil(spritetype *, XSPRITE *);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(BiteSeqCallback);
|
||||
|
||||
AISTATE eelIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE eelFlyIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE eelChase = { kAiStateChase, 0, -1, 0, NULL, MoveForward, thinkChase, &eelIdle };
|
||||
AISTATE eelPonder = { kAiStateOther, 0, -1, 0, NULL, NULL, thinkPonder, NULL };
|
||||
AISTATE eelGoto = { kAiStateMove, 0, -1, 600, NULL, NULL, thinkGoto, &eelIdle };
|
||||
AISTATE eelBite = { kAiStateChase, 7, nBiteClient, 60, NULL, NULL, NULL, &eelChase };
|
||||
AISTATE eelRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &eelChase };
|
||||
AISTATE eelSearch = { kAiStateSearch, 0, -1, 120, NULL, MoveForward, thinkSearch, &eelIdle };
|
||||
AISTATE eelSwoop = { kAiStateOther, 0, -1, 60, NULL, MoveSwoop, thinkChase, &eelChase };
|
||||
AISTATE eelFly = { kAiStateMove, 0, -1, 0, NULL, MoveAscend, thinkChase, &eelChase };
|
||||
AISTATE eelTurn = { kAiStateMove, 0, -1, 60, NULL, aiMoveTurn, NULL, &eelChase };
|
||||
AISTATE eelHide = { kAiStateOther, 0, -1, 0, NULL, MoveToCeil, MoveForward, NULL };
|
||||
AISTATE eelDodgeUp = { kAiStateMove, 0, -1, 120, NULL, MoveDodgeUp, NULL, &eelChase };
|
||||
AISTATE eelDodgeUpRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &eelChase };
|
||||
AISTATE eelDodgeUpLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &eelChase };
|
||||
AISTATE eelDodgeDown = { kAiStateMove, 0, -1, 120, NULL, MoveDodgeDown, NULL, &eelChase };
|
||||
AISTATE eelDodgeDownRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &eelChase };
|
||||
AISTATE eelDodgeDownLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &eelChase };
|
||||
|
||||
static void BiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
spritetype *pSprite = &sprite[pXSprite->reference];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int dx = Cos(pSprite->ang) >> 16;
|
||||
int dy = Sin(pSprite->ang) >> 16;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2;
|
||||
int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2;
|
||||
/*
|
||||
* workaround for
|
||||
* pXSprite->target >= 0 && pXSprite->target < kMaxSprites in file NBlood/source/blood/src/aiboneel.cpp at line 86
|
||||
* The value of pXSprite->target is -1.
|
||||
* copied from lines 177:181
|
||||
* resolves this case, but may cause other issues?
|
||||
*/
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, height2-height, VECTOR_TYPE_7);
|
||||
}
|
||||
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
if (pDudeExtraE->at8 && pDudeExtraE->at4 < 10)
|
||||
pDudeExtraE->at4++;
|
||||
else if (pDudeExtraE->at4 >= 10 && pDudeExtraE->at8)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
aiNewState(pSprite, pXSprite, &eelTurn);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
thinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
thinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkPonder(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
int height2 = (dudeInfo[pTarget->type-kDudeBase].eyeHeight*pTarget->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (height2-height < -0x2000 && nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeUp);
|
||||
else if (height2-height > 0xccc && nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeDown);
|
||||
else if (height2-height < 0xccc && nDist < 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeUp);
|
||||
else if (height2-height > 0xccc && nDist < 0x1400 && nDist > 0x800 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeDown);
|
||||
else if (height2-height < -0x2000 && nDist < 0x1400 && nDist > 0x800 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeUp);
|
||||
else if (height2-height < -0x2000 && klabs(nDeltaAngle) < 85 && nDist > 0x1400)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeUp);
|
||||
else if (height2-height > 0xccc)
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeDown);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &eelDodgeUp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
aiNewState(pSprite, pXSprite, &eelGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void MoveDodgeUp(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x8000;
|
||||
}
|
||||
|
||||
static void MoveDodgeDown(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
if (pXSprite->dodgeDir == 0)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x44444;
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
int top2, bottom2;
|
||||
GetSpriteExtents(pTarget, &top2, &bottom2);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x399 && top2 > top && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelSwoop);
|
||||
else if (nDist <= 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelBite);
|
||||
else if (bottom2 > top && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelSwoop);
|
||||
else if (top2 < top && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &eelFly);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pXSprite->target = -1;
|
||||
aiNewState(pSprite, pXSprite, &eelSearch);
|
||||
}
|
||||
|
||||
static void MoveForward(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<26)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= 0x399)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void MoveSwoop(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<26)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x8000) && nDist <= 0x399)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x22222;
|
||||
}
|
||||
|
||||
static void MoveAscend(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<26)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x399)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x8000;
|
||||
}
|
||||
|
||||
void MoveToCeil(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = pSprite->z;
|
||||
int nSector = pSprite->sectnum;
|
||||
if (z - pXSprite->targetZ < 0x1000)
|
||||
{
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
pDudeExtraE->at8 = 0;
|
||||
pSprite->hitag = 0;
|
||||
aiNewState(pSprite, pXSprite, &eelIdle);
|
||||
}
|
||||
else
|
||||
aiSetTarget(pXSprite, x, y, sector[nSector].ceilingz);
|
||||
}
|
44
source/blood/src/aiboneel.h
Normal file
44
source/blood/src/aiboneel.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE eelIdle;
|
||||
extern AISTATE eelFlyIdle;
|
||||
extern AISTATE eelChase;
|
||||
extern AISTATE eelPonder;
|
||||
extern AISTATE eelGoto;
|
||||
extern AISTATE eelBite;
|
||||
extern AISTATE eelRecoil;
|
||||
extern AISTATE eelSearch;
|
||||
extern AISTATE eelSwoop;
|
||||
extern AISTATE eelFly;
|
||||
extern AISTATE eelTurn;
|
||||
extern AISTATE eelHide;
|
||||
extern AISTATE eelDodgeUp;
|
||||
extern AISTATE eelDodgeUpRight;
|
||||
extern AISTATE eelDodgeUpLeft;
|
||||
extern AISTATE eelDodgeDown;
|
||||
extern AISTATE eelDodgeDownRight;
|
||||
extern AISTATE eelDodgeDownLeft;
|
||||
|
267
source/blood/src/aiburn.cpp
Normal file
267
source/blood/src/aiburn.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aiburn.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BurnSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype*, XSPRITE*);
|
||||
static void thinkGoto(spritetype*, XSPRITE*);
|
||||
static void thinkChase(spritetype*, XSPRITE*);
|
||||
|
||||
static int nBurnClient = seqRegisterClient(BurnSeqCallback);
|
||||
|
||||
AISTATE cultistBurnIdle = { kAiStateIdle, 3, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE cultistBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE cultistBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &cultistBurnSearch };
|
||||
AISTATE cultistBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &cultistBurnSearch };
|
||||
AISTATE cultistBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &cultistBurnChase };
|
||||
|
||||
AISTATE zombieABurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE zombieABurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &zombieABurnSearch };
|
||||
AISTATE zombieABurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, NULL };
|
||||
AISTATE zombieABurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &zombieABurnChase };
|
||||
|
||||
AISTATE zombieFBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE zombieFBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &zombieFBurnSearch };
|
||||
AISTATE zombieFBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, NULL };
|
||||
AISTATE zombieFBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &zombieFBurnChase };
|
||||
|
||||
AISTATE innocentBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE innocentBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &zombieFBurnSearch };
|
||||
AISTATE innocentBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, NULL };
|
||||
AISTATE innocentBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &zombieFBurnChase };
|
||||
|
||||
AISTATE beastBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE beastBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &beastBurnSearch };
|
||||
AISTATE beastBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &beastBurnSearch };
|
||||
AISTATE beastBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &beastBurnChase };
|
||||
|
||||
AISTATE tinycalebBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE tinycalebBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &tinycalebBurnSearch };
|
||||
AISTATE tinycalebBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &tinycalebBurnSearch };
|
||||
AISTATE tinycalebBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &tinycalebBurnChase };
|
||||
|
||||
AISTATE GDXGenDudeBurnIdle = { kAiStateIdle, 3, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE GDXGenDudeBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE GDXGenDudeBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &GDXGenDudeBurnSearch };
|
||||
AISTATE GDXGenDudeBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &GDXGenDudeBurnSearch };
|
||||
AISTATE GDXGenDudeBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &GDXGenDudeBurnChase };
|
||||
|
||||
static void BurnSeqCallback(int, int)
|
||||
{
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 240:
|
||||
aiNewState(pSprite, pXSprite, &cultistBurnSearch);
|
||||
break;
|
||||
case 241:
|
||||
aiNewState(pSprite, pXSprite, &zombieABurnSearch);
|
||||
break;
|
||||
case 242:
|
||||
aiNewState(pSprite, pXSprite, &zombieFBurnSearch);
|
||||
break;
|
||||
case 239:
|
||||
aiNewState(pSprite, pXSprite, &innocentBurnSearch);
|
||||
break;
|
||||
case 253:
|
||||
aiNewState(pSprite, pXSprite, &beastBurnSearch);
|
||||
break;
|
||||
case 252:
|
||||
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
|
||||
break;
|
||||
case kGDXGenDudeBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 240:
|
||||
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
|
||||
break;
|
||||
case 241:
|
||||
aiNewState(pSprite, pXSprite, &zombieABurnGoto);
|
||||
break;
|
||||
case 242:
|
||||
aiNewState(pSprite, pXSprite, &zombieFBurnGoto);
|
||||
break;
|
||||
case 239:
|
||||
aiNewState(pSprite, pXSprite, &innocentBurnGoto);
|
||||
break;
|
||||
case 253:
|
||||
aiNewState(pSprite, pXSprite, &beastBurnGoto);
|
||||
break;
|
||||
case 252:
|
||||
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
|
||||
break;
|
||||
case kGDXGenDudeBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 240:
|
||||
aiNewState(pSprite, pXSprite, &cultistBurnSearch);
|
||||
break;
|
||||
case 241:
|
||||
aiNewState(pSprite, pXSprite, &zombieABurnSearch);
|
||||
break;
|
||||
case 242:
|
||||
aiNewState(pSprite, pXSprite, &zombieFBurnSearch);
|
||||
break;
|
||||
case 239:
|
||||
aiNewState(pSprite, pXSprite, &innocentBurnSearch);
|
||||
break;
|
||||
case 253:
|
||||
aiNewState(pSprite, pXSprite, &beastBurnSearch);
|
||||
break;
|
||||
case 252:
|
||||
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
|
||||
break;
|
||||
case kGDXGenDudeBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x333 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 240:
|
||||
aiNewState(pSprite, pXSprite, &cultistBurnAttack);
|
||||
break;
|
||||
case 241:
|
||||
aiNewState(pSprite, pXSprite, &zombieABurnAttack);
|
||||
break;
|
||||
case 242:
|
||||
aiNewState(pSprite, pXSprite, &zombieFBurnAttack);
|
||||
break;
|
||||
case 239:
|
||||
aiNewState(pSprite, pXSprite, &innocentBurnAttack);
|
||||
break;
|
||||
case 253:
|
||||
aiNewState(pSprite, pXSprite, &beastBurnAttack);
|
||||
break;
|
||||
case 252:
|
||||
aiNewState(pSprite, pXSprite, &tinycalebBurnAttack);
|
||||
break;
|
||||
case kGDXGenDudeBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 240:
|
||||
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
|
||||
break;
|
||||
case 241:
|
||||
aiNewState(pSprite, pXSprite, &zombieABurnGoto);
|
||||
break;
|
||||
case 242:
|
||||
aiNewState(pSprite, pXSprite, &zombieFBurnGoto);
|
||||
break;
|
||||
case 239:
|
||||
aiNewState(pSprite, pXSprite, &innocentBurnGoto);
|
||||
break;
|
||||
case 253:
|
||||
aiNewState(pSprite, pXSprite, &beastBurnGoto);
|
||||
break;
|
||||
case 252:
|
||||
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
|
||||
break;
|
||||
case kGDXGenDudeBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
pXSprite->target = -1;
|
||||
}
|
56
source/blood/src/aiburn.h
Normal file
56
source/blood/src/aiburn.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE cultistBurnIdle;
|
||||
extern AISTATE cultistBurnChase;
|
||||
extern AISTATE cultistBurnGoto;
|
||||
extern AISTATE cultistBurnSearch;
|
||||
extern AISTATE cultistBurnAttack;
|
||||
extern AISTATE zombieABurnChase;
|
||||
extern AISTATE zombieABurnGoto;
|
||||
extern AISTATE zombieABurnSearch;
|
||||
extern AISTATE zombieABurnAttack;
|
||||
extern AISTATE zombieFBurnChase;
|
||||
extern AISTATE zombieFBurnGoto;
|
||||
extern AISTATE zombieFBurnSearch;
|
||||
extern AISTATE zombieFBurnAttack;
|
||||
extern AISTATE innocentBurnChase;
|
||||
extern AISTATE innocentBurnGoto;
|
||||
extern AISTATE innocentBurnSearch;
|
||||
extern AISTATE innocentBurnAttack;
|
||||
extern AISTATE beastBurnChase;
|
||||
extern AISTATE beastBurnGoto;
|
||||
extern AISTATE beastBurnSearch;
|
||||
extern AISTATE beastBurnAttack;
|
||||
extern AISTATE tinycalebBurnChase;
|
||||
extern AISTATE tinycalebBurnGoto;
|
||||
extern AISTATE tinycalebBurnSearch;
|
||||
extern AISTATE tinycalebBurnAttack;
|
||||
extern AISTATE GDXGenDudeBurnIdle;
|
||||
extern AISTATE GDXGenDudeBurnChase;
|
||||
extern AISTATE GDXGenDudeBurnGoto;
|
||||
extern AISTATE GDXGenDudeBurnSearch;
|
||||
extern AISTATE GDXGenDudeBurnAttack;
|
||||
|
423
source/blood/src/aicaleb.cpp
Normal file
423
source/blood/src/aicaleb.cpp
Normal file
|
@ -0,0 +1,423 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aicaleb.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void SeqAttackCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void thinkSwimGoto(spritetype *, XSPRITE *);
|
||||
static void thinkSwimChase(spritetype *, XSPRITE *);
|
||||
static void sub_65D04(spritetype *, XSPRITE *);
|
||||
static void sub_65F44(spritetype *, XSPRITE *);
|
||||
static void sub_661E0(spritetype *, XSPRITE *);
|
||||
|
||||
static int nAttackClient = seqRegisterClient(SeqAttackCallback);
|
||||
|
||||
AISTATE tinycalebIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE tinycalebChase = { kAiStateChase, 6, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE tinycalebDodge = { kAiStateMove, 6, -1, 90, NULL, aiMoveDodge, NULL, &tinycalebChase };
|
||||
AISTATE tinycalebGoto = { kAiStateMove, 6, -1, 600, NULL, aiMoveForward, thinkGoto, &tinycalebIdle };
|
||||
AISTATE tinycalebAttack = { kAiStateChase, 0, nAttackClient, 120, NULL, NULL, NULL, &tinycalebChase };
|
||||
AISTATE tinycalebSearch = { kAiStateSearch, 6, -1, 120, NULL, aiMoveForward, thinkSearch, &tinycalebIdle };
|
||||
AISTATE tinycalebRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &tinycalebDodge };
|
||||
AISTATE tinycalebTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &tinycalebDodge };
|
||||
AISTATE tinycalebSwimIdle = { kAiStateIdle, 10, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE tinycalebSwimChase = { kAiStateChase, 8, -1, 0, NULL, sub_65D04, thinkSwimChase, NULL };
|
||||
AISTATE tinycalebSwimDodge = { kAiStateMove, 8, -1, 90, NULL, aiMoveDodge, NULL, &tinycalebSwimChase };
|
||||
AISTATE tinycalebSwimGoto = { kAiStateMove, 8, -1, 600, NULL, aiMoveForward, thinkSwimGoto, &tinycalebSwimIdle };
|
||||
AISTATE tinycalebSwimSearch = { kAiStateSearch, 8, -1, 120, NULL, aiMoveForward, thinkSearch, &tinycalebSwimIdle };
|
||||
AISTATE tinycalebSwimAttack = { kAiStateChase, 10, nAttackClient, 0, NULL, NULL, NULL, &tinycalebSwimChase };
|
||||
AISTATE tinycalebSwimRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &tinycalebSwimDodge };
|
||||
AISTATE tinycaleb139660 = { kAiStateOther, 8, -1, 120, NULL, sub_65F44, thinkSwimChase, &tinycalebSwimChase };
|
||||
AISTATE tinycaleb13967C = { kAiStateOther, 8, -1, 0, NULL, sub_661E0, thinkSwimChase, &tinycalebSwimChase };
|
||||
AISTATE tinycaleb139698 = { kAiStateOther, 8, -1, 120, NULL, aiMoveTurn, NULL, &tinycalebSwimChase };
|
||||
|
||||
static void SeqAttackCallback(int, int nXSprite)
|
||||
{
|
||||
int nSprite = xsprite[nXSprite].reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
int dz = gDudeSlope[nXSprite];
|
||||
dx += Random2(1500);
|
||||
dy += Random2(1500);
|
||||
dz += Random2(1500);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
int r1 = Random3(500);
|
||||
int r2 = Random3(1000);
|
||||
int r3 = Random3(1000);
|
||||
actFireVector(pSprite, 0, 0, dx+r3, dy+r2, dz+r1, VECTOR_TYPE_1);
|
||||
}
|
||||
if (Chance(0x8000))
|
||||
sfxPlay3DSound(pSprite, 10000+Random(5), -1, 0);
|
||||
if (Chance(0x8000))
|
||||
sfxPlay3DSound(pSprite, 1001, -1, 0);
|
||||
else
|
||||
sfxPlay3DSound(pSprite, 1002, -1, 0);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSearch);
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
else
|
||||
{
|
||||
aiPlay3DSound(pSprite, 11000+Random(4), AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSearch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int nXSprite = sprite[pXSprite->reference].extra;
|
||||
gDudeSlope[nXSprite] = divscale(pTarget->z-pSprite->z, nDist, 10);
|
||||
if (nDist < 0x599 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimAttack);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebAttack);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimAttack);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebAttack);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimDodge);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimAttack);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebAttack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimGoto);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycalebGoto);
|
||||
if (Chance(0x2000))
|
||||
sfxPlay3DSound(pSprite, 10000 + Random(5), -1, 0);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void thinkSwimGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkSwimChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = pDudeInfo->eyeHeight+pSprite->z;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int UNUSED(floorZ) = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimAttack);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &tinycaleb13967C);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
aiNewState(pSprite, pXSprite, &tinycalebSwimGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void sub_65D04(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Random(64) < 32 && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>2;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void sub_65F44(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = z2 - z;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -dz;
|
||||
}
|
||||
|
||||
static void sub_661E0(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = (z2 - z)<<3;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = dz;
|
||||
}
|
43
source/blood/src/aicaleb.h
Normal file
43
source/blood/src/aicaleb.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE tinycalebIdle;
|
||||
extern AISTATE tinycalebChase;
|
||||
extern AISTATE tinycalebDodge;
|
||||
extern AISTATE tinycalebGoto;
|
||||
extern AISTATE tinycalebAttack;
|
||||
extern AISTATE tinycalebSearch;
|
||||
extern AISTATE tinycalebRecoil;
|
||||
extern AISTATE tinycalebTeslaRecoil;
|
||||
extern AISTATE tinycalebSwimIdle;
|
||||
extern AISTATE tinycalebSwimChase;
|
||||
extern AISTATE tinycalebSwimDodge;
|
||||
extern AISTATE tinycalebSwimGoto;
|
||||
extern AISTATE tinycalebSwimSearch;
|
||||
extern AISTATE tinycalebSwimAttack;
|
||||
extern AISTATE tinycalebSwimRecoil;
|
||||
extern AISTATE tinycaleb139660;
|
||||
extern AISTATE tinycaleb13967C;
|
||||
extern AISTATE tinycaleb139698;
|
489
source/blood/src/aicerber.cpp
Normal file
489
source/blood/src/aicerber.cpp
Normal file
|
@ -0,0 +1,489 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aicerber.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BiteSeqCallback(int, int);
|
||||
static void BurnSeqCallback(int, int);
|
||||
static void BurnSeqCallback2(int, int);
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(BiteSeqCallback);
|
||||
static int nBurnClient = seqRegisterClient(BurnSeqCallback);
|
||||
static int nBurnClient2 = seqRegisterClient(BurnSeqCallback2);
|
||||
|
||||
AISTATE cerberusIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE cerberusSearch = { kAiStateSearch, 7, -1, 1800, NULL, aiMoveForward, thinkSearch, &cerberusIdle };
|
||||
AISTATE cerberusChase = { kAiStateChase, 7, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE cerberusRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &cerberusSearch };
|
||||
AISTATE cerberusTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &cerberusSearch };
|
||||
AISTATE cerberusGoto = { kAiStateMove, 7, -1, 600, NULL, aiMoveForward, thinkGoto, &cerberusIdle };
|
||||
AISTATE cerberusBite = { kAiStateChase, 6, nBiteClient, 60, NULL, NULL, NULL, &cerberusChase };
|
||||
AISTATE cerberusBurn = { kAiStateChase, 6, nBurnClient, 60, NULL, NULL, NULL, &cerberusChase };
|
||||
AISTATE cerberus3Burn = { kAiStateChase, 6, nBurnClient2, 60, NULL, NULL, NULL, &cerberusChase };
|
||||
AISTATE cerberus2Idle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE cerberus2Search = { kAiStateSearch, 7, -1, 1800, NULL, aiMoveForward, thinkSearch, &cerberus2Idle };
|
||||
AISTATE cerberus2Chase = { kAiStateChase, 7, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE cerberus2Recoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &cerberus2Search };
|
||||
AISTATE cerberus2Goto = { kAiStateMove, 7, -1, 600, NULL, aiMoveForward, thinkGoto, &cerberus2Idle };
|
||||
AISTATE cerberus2Bite = { kAiStateChase, 6, nBiteClient, 60, NULL, NULL, NULL, &cerberus2Chase };
|
||||
AISTATE cerberus2Burn = { kAiStateChase, 6, nBurnClient, 60, NULL, NULL, NULL, &cerberus2Chase };
|
||||
AISTATE cerberus4Burn = { kAiStateChase, 6, nBurnClient2, 60, NULL, NULL, NULL, &cerberus2Chase };
|
||||
AISTATE cerberus139890 = { kAiStateOther, 7, -1, 120, NULL, aiMoveTurn, NULL, &cerberusChase };
|
||||
AISTATE cerberus1398AC = { kAiStateOther, 7, -1, 120, NULL, aiMoveTurn, NULL, &cerberusChase };
|
||||
|
||||
static void BiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int dz = pTarget->z-pSprite->z;
|
||||
actFireVector(pSprite, 350, -100, dx, dy, dz, VECTOR_TYPE_14);
|
||||
actFireVector(pSprite, -350, 0, dx, dy, dz, VECTOR_TYPE_14);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_14);
|
||||
}
|
||||
|
||||
static void BurnSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int height = pDudeInfo->eyeHeight*pSprite->yrepeat;
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height; // ???
|
||||
TARGETTRACK tt1 = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa };
|
||||
Aim aim;
|
||||
aim.dx = Cos(pSprite->ang)>>16;
|
||||
aim.dy = Sin(pSprite->ang)>>16;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
int nClosest = 0x7fffffff;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt1.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt1.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt1.at8)
|
||||
{
|
||||
int tz = pSprite2->z-pSprite->z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
actFireMissile(pSprite, -350, 0, aim.dx, aim.dy, aim.dz, 313);
|
||||
actFireMissile(pSprite, 350, -100, aim.dx, aim.dy, aim.dz, 313);
|
||||
break;
|
||||
case 228:
|
||||
actFireMissile(pSprite, 350, -100, aim.dx, aim.dy, aim.dz, 313);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void BurnSeqCallback2(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int height = pDudeInfo->eyeHeight*pSprite->yrepeat;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height; // ???
|
||||
TARGETTRACK tt1 = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa };
|
||||
Aim aim;
|
||||
int ax, ay, az;
|
||||
aim.dx = ax = Cos(pSprite->ang)>>16;
|
||||
aim.dy = ay = Sin(pSprite->ang)>>16;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
az = 0;
|
||||
int nClosest = 0x7fffffff;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt1.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt1.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt1.at8)
|
||||
{
|
||||
DUDEINFO *pDudeInfo2 = &dudeInfo[pSprite2->type - kDudeBase];
|
||||
int height = (pDudeInfo2->aimHeight*pSprite2->yrepeat)<<2;
|
||||
int tz = (z2-height)-z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
actFireMissile(pSprite, 350, -100, aim.dx, aim.dy, -aim.dz, 308);
|
||||
actFireMissile(pSprite, -350, 0, ax, ay, az, 308);
|
||||
break;
|
||||
case 228:
|
||||
actFireMissile(pSprite, 350, -100, aim.dx, aim.dy, -aim.dz, 308);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
if (pDudeExtraE->at8 && pDudeExtraE->at4 < 10)
|
||||
pDudeExtraE->at4++;
|
||||
else if (pDudeExtraE->at4 >= 10 && pDudeExtraE->at8)
|
||||
{
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
if (pSprite->type == 227)
|
||||
aiNewState(pSprite, pXSprite, &cerberus139890);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &cerberus1398AC);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
pDudeExtraE->at0 = 0;
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
pDudeExtraE->at0 = 0;
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusSearch);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Search);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusGoto);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Goto);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusSearch);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Search);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusSearch);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Search);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x1b00 && nDist > 0xd00 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusBurn);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Burn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0xb00 && nDist > 0x500 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberus3Burn);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus4Burn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x200 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &cerberusBite);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 211)
|
||||
aiNewState(pSprite, pXSprite, &cerberusBite);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cerberusBite);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 228:
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Bite);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 211)
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Bite);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Bite);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 227:
|
||||
aiNewState(pSprite, pXSprite, &cerberusGoto);
|
||||
break;
|
||||
case 228:
|
||||
aiNewState(pSprite, pXSprite, &cerberus2Goto);
|
||||
break;
|
||||
}
|
||||
pXSprite->target = -1;
|
||||
}
|
44
source/blood/src/aicerber.h
Normal file
44
source/blood/src/aicerber.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE cerberusIdle;
|
||||
extern AISTATE cerberusSearch;
|
||||
extern AISTATE cerberusChase;
|
||||
extern AISTATE cerberusRecoil;
|
||||
extern AISTATE cerberusTeslaRecoil;
|
||||
extern AISTATE cerberusGoto;
|
||||
extern AISTATE cerberusBite;
|
||||
extern AISTATE cerberusBurn;
|
||||
extern AISTATE cerberus3Burn;
|
||||
extern AISTATE cerberus2Idle;
|
||||
extern AISTATE cerberus2Search;
|
||||
extern AISTATE cerberus2Chase;
|
||||
extern AISTATE cerberus2Recoil;
|
||||
extern AISTATE cerberus2Goto;
|
||||
extern AISTATE cerberus2Bite;
|
||||
extern AISTATE cerberus2Burn;
|
||||
extern AISTATE cerberus4Burn;
|
||||
extern AISTATE cerberus139890;
|
||||
extern AISTATE cerberus1398AC;
|
659
source/blood/src/aicult.cpp
Normal file
659
source/blood/src/aicult.cpp
Normal file
|
@ -0,0 +1,659 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aicult.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void TommySeqCallback(int, int);
|
||||
static void TeslaSeqCallback(int, int);
|
||||
static void ShotSeqCallback(int, int);
|
||||
static void ThrowSeqCallback(int, int);
|
||||
static void sub_68170(int, int);
|
||||
static void sub_68230(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
static int nTommyClient = seqRegisterClient(TommySeqCallback);
|
||||
static int nTeslaClient = seqRegisterClient(TeslaSeqCallback);
|
||||
static int nShotClient = seqRegisterClient(ShotSeqCallback);
|
||||
static int nThrowClient = seqRegisterClient(ThrowSeqCallback);
|
||||
static int n68170Client = seqRegisterClient(sub_68170);
|
||||
static int n68230Client = seqRegisterClient(sub_68230);
|
||||
|
||||
AISTATE cultistIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE cultistProneIdle = { kAiStateIdle, 17, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE fanaticProneIdle = { kAiStateIdle, 17, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE cultistProneIdle3 = { kAiStateIdle, 17, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE cultistChase = { kAiStateChase, 9, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE fanaticChase = { kAiStateChase, 0, -1, 0, NULL, aiMoveTurn, thinkChase, NULL };
|
||||
AISTATE cultistDodge = { kAiStateMove, 9, -1, 90, NULL, aiMoveDodge, NULL, &cultistChase };
|
||||
AISTATE cultistGoto = { kAiStateMove, 9, -1, 600, NULL, aiMoveForward, thinkGoto, &cultistIdle };
|
||||
AISTATE cultistProneChase = { kAiStateChase, 14, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE cultistProneDodge = { kAiStateMove, 14, -1, 90, NULL, aiMoveDodge, NULL, &cultistProneChase };
|
||||
AISTATE cultistTThrow = { kAiStateChase, 7, nThrowClient, 120, NULL, NULL, NULL, &cultistTFire };
|
||||
AISTATE cultistSThrow = { kAiStateChase, 7, nThrowClient, 120, NULL, NULL, NULL, &cultistSFire };
|
||||
AISTATE cultistTsThrow = { kAiStateChase, 7, nThrowClient, 120, NULL, NULL, NULL, &cultistTsFire };
|
||||
AISTATE cultistDThrow = { kAiStateChase, 7, nThrowClient, 120, NULL, NULL, NULL, &cultistChase };
|
||||
AISTATE cultist139A78 = { kAiStateChase, 7, n68170Client, 120, NULL, NULL, NULL, &cultistChase };
|
||||
AISTATE cultist139A94 = { kAiStateChase, 7, n68230Client, 120, NULL, NULL, NULL, &cultistIdle };
|
||||
AISTATE cultist139AB0 = { kAiStateChase, 7, n68230Client, 120, NULL, NULL, thinkSearch, &cultist139A94 };
|
||||
AISTATE cultist139ACC = { kAiStateChase, 7, n68230Client, 120, NULL, NULL, thinkSearch, &cultist139AB0 };
|
||||
AISTATE cultist139AE8 = { kAiStateChase, 7, n68230Client, 120, NULL, NULL, thinkSearch, &cultist139AE8 };
|
||||
AISTATE cultistSearch = { kAiStateSearch, 9, -1, 1800, NULL, aiMoveForward, thinkSearch, &cultistIdle };
|
||||
AISTATE cultistSFire = { kAiStateChase, 6, nShotClient, 60, NULL, NULL, NULL, &cultistChase };
|
||||
AISTATE cultistTFire = { kAiStateChase, 6, nTommyClient, 0, NULL, aiMoveTurn, thinkChase, &cultistTFire };
|
||||
AISTATE cultistTsFire = { kAiStateChase, 6, nTeslaClient, 0, NULL, aiMoveTurn, thinkChase, &cultistChase };
|
||||
AISTATE cultistSProneFire = { kAiStateChase, 8, nShotClient, 60, NULL, NULL, NULL, &cultistProneChase };
|
||||
AISTATE cultistTProneFire = { kAiStateChase, 8, nTommyClient, 0, NULL, aiMoveTurn, thinkChase, &cultistTProneFire };
|
||||
AISTATE cultistTsProneFire = { kAiStateChase, 8, nTeslaClient, 0, NULL, aiMoveTurn, NULL, &cultistTsProneFire };
|
||||
AISTATE cultistRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &cultistDodge };
|
||||
AISTATE cultistProneRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &cultistProneDodge };
|
||||
AISTATE cultistTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &cultistDodge };
|
||||
AISTATE cultistSwimIdle = { kAiStateIdle, 13, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE cultistSwimChase = { kAiStateChase, 13, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE cultistSwimDodge = { kAiStateMove, 13, -1, 90, NULL, aiMoveDodge, NULL, &cultistSwimChase };
|
||||
AISTATE cultistSwimGoto = { kAiStateMove, 13, -1, 600, NULL, aiMoveForward, thinkGoto, &cultistSwimIdle };
|
||||
AISTATE cultistSwimSearch = { kAiStateSearch, 13, -1, 1800, NULL, aiMoveForward, thinkSearch, &cultistSwimIdle };
|
||||
AISTATE cultistSSwimFire = { kAiStateChase, 8, nShotClient, 60, NULL, NULL, NULL, &cultistSwimChase };
|
||||
AISTATE cultistTSwimFire = { kAiStateChase, 8, nTommyClient, 0, NULL, aiMoveTurn, thinkChase, &cultistTSwimFire };
|
||||
AISTATE cultistTsSwimFire = { kAiStateChase, 8, nTeslaClient, 0, NULL, aiMoveTurn, thinkChase, &cultistTsSwimFire };
|
||||
AISTATE cultistSwimRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &cultistSwimDodge };
|
||||
|
||||
static void TommySeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang) >> 16;
|
||||
int dy = Sin(pSprite->ang) >> 16;
|
||||
int dz = gDudeSlope[nXSprite];
|
||||
dx += Random3((5-gGameOptions.nDifficulty)*1000);
|
||||
dy += Random3((5-gGameOptions.nDifficulty)*1000);
|
||||
dz += Random3((5-gGameOptions.nDifficulty)*500);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_2);
|
||||
sfxPlay3DSound(pSprite, 4001, -1, 0);
|
||||
}
|
||||
|
||||
static void TeslaSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (Chance(dword_138BB0[gGameOptions.nDifficulty]))
|
||||
{
|
||||
int dx = Cos(pSprite->ang) >> 16;
|
||||
int dy = Sin(pSprite->ang) >> 16;
|
||||
int dz = gDudeSlope[nXSprite];
|
||||
dx += Random3((5-gGameOptions.nDifficulty)*1000);
|
||||
dy += Random3((5-gGameOptions.nDifficulty)*1000);
|
||||
dz += Random3((5-gGameOptions.nDifficulty)*500);
|
||||
actFireMissile(pSprite, 0, 0, dx, dy, dz, 306);
|
||||
sfxPlay3DSound(pSprite, 470, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void ShotSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang) >> 16;
|
||||
int dy = Sin(pSprite->ang) >> 16;
|
||||
int dz = gDudeSlope[nXSprite];
|
||||
dx += Random2((5-gGameOptions.nDifficulty)*1000-500);
|
||||
dy += Random2((5-gGameOptions.nDifficulty)*1000-500);
|
||||
dz += Random2((5-gGameOptions.nDifficulty)*500);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int r1 = Random3(500);
|
||||
int r2 = Random3(1000);
|
||||
int r3 = Random3(1000);
|
||||
actFireVector(pSprite, 0, 0, dx+r3, dy+r2, dz+r1, VECTOR_TYPE_1);
|
||||
}
|
||||
if (Chance(0x8000))
|
||||
sfxPlay3DSound(pSprite, 1001, -1, 0);
|
||||
else
|
||||
sfxPlay3DSound(pSprite, 1002, -1, 0);
|
||||
}
|
||||
|
||||
static void ThrowSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nMissile = 418;
|
||||
if (gGameOptions.nDifficulty > 2)
|
||||
nMissile = 419;
|
||||
char v4 = Chance(0x6000);
|
||||
sfxPlay3DSound(pSprite, 455, -1, 0);
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
int dx = pTarget->x - pSprite->x;
|
||||
int dy = pTarget->y - pSprite->y;
|
||||
int dz = pTarget->z - pSprite->z;
|
||||
int nDist = approxDist(dx, dy);
|
||||
int nDist2 = nDist / 540;
|
||||
if (nDist > 0x1e00)
|
||||
v4 = 0;
|
||||
spritetype *pMissile = actFireThing(pSprite, 0, 0, dz/128-14500, nMissile, (nDist2<<23)/120);
|
||||
if (v4)
|
||||
xsprite[pMissile->extra].Impact = 1;
|
||||
else
|
||||
evPost(pMissile->index, 3, 120*(1+Random(2)), COMMAND_ID_1);
|
||||
}
|
||||
|
||||
static void sub_68170(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nMissile = 418;
|
||||
if (gGameOptions.nDifficulty > 2)
|
||||
nMissile = 419;
|
||||
sfxPlay3DSound(pSprite, 455, -1, 0);
|
||||
spritetype *pMissile = actFireThing(pSprite, 0, 0, gDudeSlope[nXSprite]-9460, nMissile, 0x133333);
|
||||
evPost(pMissile->index, 3, 120*(2+Random(2)), COMMAND_ID_1);
|
||||
}
|
||||
|
||||
static void sub_68230(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nMissile = 418;
|
||||
if (gGameOptions.nDifficulty > 2)
|
||||
nMissile = 419;
|
||||
sfxPlay3DSound(pSprite, 455, -1, 0);
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
int dx = pTarget->x - pSprite->x;
|
||||
int dy = pTarget->y - pSprite->y;
|
||||
int dz = pTarget->z - pSprite->z;
|
||||
int nDist = approxDist(dx, dy);
|
||||
int nDist2 = nDist / 540;
|
||||
spritetype *pMissile = actFireThing(pSprite, 0, 0, dz/128-14500, nMissile, (nDist2<<17)/120);
|
||||
xsprite[pMissile->extra].Impact = 1;
|
||||
}
|
||||
|
||||
static char TargetNearExplosion(spritetype *pSprite)
|
||||
{
|
||||
for (short nSprite = headspritesect[pSprite->sectnum]; nSprite >= 0; nSprite = nextspritesect[nSprite])
|
||||
{
|
||||
if (sprite[nSprite].type == 418 || sprite[nSprite].statnum == 2)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
sub_5F15C(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 5120 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
switch (pXSprite->medium)
|
||||
{
|
||||
case 0:
|
||||
aiNewState(pSprite, pXSprite, &cultistSearch);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
switch (pXSprite->medium)
|
||||
{
|
||||
case 0:
|
||||
aiNewState(pSprite, pXSprite, &cultistGoto);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimGoto);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
switch (pXSprite->medium)
|
||||
{
|
||||
case 0:
|
||||
aiNewState(pSprite, pXSprite, &cultistSearch);
|
||||
if (pSprite->type == 201)
|
||||
aiPlay3DSound(pSprite, 4021+Random(4), AI_SFX_PRIORITY_1, -1);
|
||||
else
|
||||
aiPlay3DSound(pSprite, 1021+Random(4), AI_SFX_PRIORITY_1, -1);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimSearch);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
switch (pXSprite->medium)
|
||||
{
|
||||
case 0:
|
||||
aiNewState(pSprite, pXSprite, &cultistSearch);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimSearch);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int nXSprite = sprite[pXSprite->reference].extra;
|
||||
gDudeSlope[nXSprite] = divscale(pTarget->z-pSprite->z, nDist, 10);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 201:
|
||||
if (nDist < 0x1e00 && nDist > 0xe00 && klabs(nDeltaAngle) < 85 && !TargetNearExplosion(pTarget)
|
||||
&& (pTarget->hitag&2) && gGameOptions.nDifficulty > 2 && IsPlayerSprite(pTarget) && gPlayer[pTarget->type-kDudePlayer1].at2e
|
||||
&& Chance(0x8000))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTThrow);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTThrow);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultistTThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x4600 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTProneFire);
|
||||
else if (sub_5BDA8(pSprite, 13) && (pXSprite->medium == 1 || pXSprite->medium == 2))
|
||||
aiNewState(pSprite, pXSprite, &cultistTSwimFire);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202)
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTSwimFire);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistDodge);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistProneDodge);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTSwimFire);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 202:
|
||||
if (nDist < 0x2c00 && nDist > 0x1400 && !TargetNearExplosion(pTarget)
|
||||
&& (pTarget->hitag&2) && gGameOptions.nDifficulty >= 2 && IsPlayerSprite(pTarget) && !gPlayer[pTarget->type-kDudePlayer1].at2e
|
||||
&& Chance(0x8000))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x3200 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 201)
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistDodge);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistProneDodge);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 247:
|
||||
if (nDist < 0x1e00 && nDist > 0xe00 && !TargetNearExplosion(pTarget)
|
||||
&& (pTarget->hitag&2) && gGameOptions.nDifficulty > 2 && IsPlayerSprite(pTarget) && gPlayer[pTarget->type-kDudePlayer1].at2e
|
||||
&& Chance(0x8000))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsThrow);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsThrow);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultistTsThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x3200 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsSwimFire);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 201)
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsSwimFire);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistDodge);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistProneDodge);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistTsSwimFire);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 248:
|
||||
if (nDist < 0x2c00 && nDist > 0x1400 && klabs(nDeltaAngle) < 85
|
||||
&& (pTarget->hitag&2) && IsPlayerSprite(pTarget))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistDThrow);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistDThrow);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultistDThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x1400 && klabs(nDeltaAngle) < 85
|
||||
&& (pTarget->hitag&2) && IsPlayerSprite(pTarget))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultist139A78);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultist139A78);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultist139A78);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 249:
|
||||
if (nDist < 0x1e00 && nDist > 0xe00 && !TargetNearExplosion(pTarget)
|
||||
&& (pTarget->hitag&2) && gGameOptions.nDifficulty > 2 && IsPlayerSprite(pTarget) && gPlayer[pTarget->type-kDudePlayer1].at2e
|
||||
&& Chance(0x8000))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 202 && pXSprite->medium != 1 && pXSprite->medium != 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &cultistSThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x3200 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 201)
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistDodge);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistProneDodge);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSFire);
|
||||
else if (sub_5BDA8(pSprite, 14) && pXSprite->medium == 0)
|
||||
aiNewState(pSprite, pXSprite, &cultistSProneFire);
|
||||
else if (pXSprite->medium == 1 || pXSprite->medium == 2)
|
||||
aiNewState(pSprite, pXSprite, &cultistSSwimFire);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (pXSprite->medium)
|
||||
{
|
||||
case 0:
|
||||
aiNewState(pSprite, pXSprite, &cultistGoto);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
aiNewState(pSprite, pXSprite, &cultistSwimGoto);
|
||||
break;
|
||||
}
|
||||
pXSprite->target = -1;
|
||||
}
|
63
source/blood/src/aicult.h
Normal file
63
source/blood/src/aicult.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE cultistIdle;
|
||||
extern AISTATE cultistProneIdle;
|
||||
extern AISTATE fanaticProneIdle;
|
||||
extern AISTATE cultistProneIdle3;
|
||||
extern AISTATE cultistChase;
|
||||
extern AISTATE fanaticChase;
|
||||
extern AISTATE cultistDodge;
|
||||
extern AISTATE cultistGoto;
|
||||
extern AISTATE cultistProneChase;
|
||||
extern AISTATE cultistProneDodge;
|
||||
extern AISTATE cultistTThrow;
|
||||
extern AISTATE cultistSThrow;
|
||||
extern AISTATE cultistTsThrow;
|
||||
extern AISTATE cultistDThrow;
|
||||
extern AISTATE cultist139A78;
|
||||
extern AISTATE cultist139A94;
|
||||
extern AISTATE cultist139AB0;
|
||||
extern AISTATE cultist139ACC;
|
||||
extern AISTATE cultist139AE8;
|
||||
extern AISTATE cultistSearch;
|
||||
extern AISTATE cultistSFire;
|
||||
extern AISTATE cultistTFire;
|
||||
extern AISTATE cultistTsFire;
|
||||
extern AISTATE cultistSProneFire;
|
||||
extern AISTATE cultistTProneFir;
|
||||
extern AISTATE cultistTsProneFire;
|
||||
extern AISTATE cultistRecoil;
|
||||
extern AISTATE cultistProneRecoil;
|
||||
extern AISTATE cultistTeslaRecoil;
|
||||
extern AISTATE cultistSwimIdle;
|
||||
extern AISTATE cultistSwimChase;
|
||||
extern AISTATE cultistSwimDodge;
|
||||
extern AISTATE cultistSwimGoto;
|
||||
extern AISTATE cultistSwimSearch;
|
||||
extern AISTATE cultistSSwimFire;
|
||||
extern AISTATE cultistTSwimFire;
|
||||
extern AISTATE cultistTsSwimFire;
|
||||
extern AISTATE cultistSwimRecoil;
|
704
source/blood/src/aigarg.cpp
Normal file
704
source/blood/src/aigarg.cpp
Normal file
|
@ -0,0 +1,704 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aigarg.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void SlashFSeqCallback(int, int);
|
||||
static void ThrowFSeqCallback(int, int);
|
||||
static void BlastSSeqCallback(int, int);
|
||||
static void ThrowSSeqCallback(int, int);
|
||||
static void thinkTarget(spritetype *, XSPRITE *);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeUp(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeDown(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void entryFStatue(spritetype *, XSPRITE *);
|
||||
static void entrySStatue(spritetype *, XSPRITE *);
|
||||
static void MoveForward(spritetype *, XSPRITE *);
|
||||
static void MoveSlow(spritetype *, XSPRITE *);
|
||||
static void MoveSwoop(spritetype *, XSPRITE *);
|
||||
static void MoveFly(spritetype *, XSPRITE *);
|
||||
static void playStatueBreakSnd(spritetype*,XSPRITE*);
|
||||
|
||||
static int nSlashFClient = seqRegisterClient(SlashFSeqCallback);
|
||||
static int nThrowFClient = seqRegisterClient(ThrowFSeqCallback);
|
||||
static int nThrowSClient = seqRegisterClient(ThrowSSeqCallback);
|
||||
static int nBlastSClient = seqRegisterClient(BlastSSeqCallback);
|
||||
|
||||
AISTATE gargoyleFIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE gargoyleStatueIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, NULL, NULL };
|
||||
AISTATE gargoyleFChase = { kAiStateChase, 0, -1, 0, NULL, MoveForward, thinkChase, &gargoyleFIdle };
|
||||
AISTATE gargoyleFGoto = { kAiStateMove, 0, -1, 600, NULL, MoveForward, thinkGoto, &gargoyleFIdle };
|
||||
AISTATE gargoyleFSlash = { kAiStateChase, 6, nSlashFClient, 120, NULL, NULL, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFThrow = { kAiStateChase, 6, nThrowFClient, 120, NULL, NULL, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleSThrow = { kAiStateChase, 6, nThrowSClient, 120, NULL, MoveForward, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleSBlast = { kAiStateChase, 7, nBlastSClient, 60, NULL, MoveSlow, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFSearch = { kAiStateSearch, 0, -1, 120, NULL, MoveForward, thinkSearch, &gargoyleFIdle };
|
||||
AISTATE gargoyleFMorph2 = { kAiStateOther, -1, -1, 0, entryFStatue, NULL, NULL, &gargoyleFIdle };
|
||||
AISTATE gargoyleFMorph = { kAiStateOther, 6, -1, 0, NULL, NULL, NULL, &gargoyleFMorph2 };
|
||||
AISTATE gargoyleSMorph2 = { kAiStateOther, -1, -1, 0, entrySStatue, NULL, NULL, &gargoyleFIdle };
|
||||
AISTATE gargoyleSMorph = { kAiStateOther, 6, -1, 0, NULL, NULL, NULL, &gargoyleSMorph2 };
|
||||
AISTATE gargoyleSwoop = { kAiStateOther, 0, -1, 120, NULL, MoveSwoop, thinkChase, &gargoyleFChase };
|
||||
AISTATE gargoyleFly = { kAiStateMove, 0, -1, 120, NULL, MoveFly, thinkChase, &gargoyleFChase };
|
||||
AISTATE gargoyleTurn = { kAiStateMove, 0, -1, 120, NULL, aiMoveTurn, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleDodgeUp = { kAiStateMove, 0, -1, 60, NULL, MoveDodgeUp, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFDodgeUpRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFDodgeUpLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleDodgeDown = { kAiStateMove, 0, -1, 120, NULL, MoveDodgeDown, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFDodgeDownRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &gargoyleFChase };
|
||||
AISTATE gargoyleFDodgeDownLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &gargoyleFChase };
|
||||
|
||||
AISTATE statueFBreakSEQ = { kAiStateOther, 5, -1, 0, entryFStatue, NULL, playStatueBreakSnd, &gargoyleFMorph2};
|
||||
AISTATE statueSBreakSEQ = { kAiStateOther, 5, -1, 0, entrySStatue, NULL, playStatueBreakSnd, &gargoyleSMorph2};
|
||||
|
||||
static void playStatueBreakSnd(spritetype* pSprite, XSPRITE* pXSprite) {
|
||||
UNREFERENCED_PARAMETER(pXSprite);
|
||||
aiPlay3DSound(pSprite, 313, AI_SFX_PRIORITY_1, -1);
|
||||
}
|
||||
|
||||
static void SlashFSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type - kDudeBase];
|
||||
int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2;
|
||||
int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2;
|
||||
int dz = height-height2;
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_13);
|
||||
int r1 = Random(50);
|
||||
int r2 = Random(50);
|
||||
actFireVector(pSprite, 0, 0, dx+r2, dy-r1, dz, VECTOR_TYPE_13);
|
||||
r1 = Random(50);
|
||||
r2 = Random(50);
|
||||
actFireVector(pSprite, 0, 0, dx-r2, dy+r1, dz, VECTOR_TYPE_13);
|
||||
}
|
||||
|
||||
static void ThrowFSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
actFireThing(&sprite[nSprite], 0, 0, gDudeSlope[nXSprite]-7500, 421, 0xeeeee);
|
||||
}
|
||||
|
||||
static void BlastSSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
wrand(); // ???
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int height = (pSprite->yrepeat*dudeInfo[pSprite->type-kDudeBase].eyeHeight) << 2;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nDist) = approxDist(dx, dy);
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height;
|
||||
TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa };
|
||||
Aim aim;
|
||||
aim.dx = Cos(pSprite->ang)>>16;
|
||||
aim.dy = Sin(pSprite->ang)>>16;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
int nClosest = 0x7fffffff;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt.at8)
|
||||
{
|
||||
int tz = pSprite2->z-pSprite->z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
if (tz > -0x333)
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
else if (tz < -0x333 && tz > -0xb33)
|
||||
aim.dz = divscale(tz, nDist, 10)+9460;
|
||||
else if (tz < -0xb33 && tz > -0x3000)
|
||||
aim.dz = divscale(tz, nDist, 10)+9460;
|
||||
else if (tz < -0x3000)
|
||||
aim.dz = divscale(tz, nDist, 10)-7500;
|
||||
else
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) || !VanillaMode()) // By NoOne: allow to fire missile in non-player targets
|
||||
{
|
||||
actFireMissile(pSprite, -120, 0, aim.dx, aim.dy, aim.dz, 311);
|
||||
actFireMissile(pSprite, 120, 0, aim.dx, aim.dy, aim.dz, 311);
|
||||
}
|
||||
}
|
||||
|
||||
static void ThrowSSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
actFireThing(pSprite, 0, 0, gDudeSlope[nXSprite]-7500, 421, Chance(0x6000) ? 0x133333 : 0x111111);
|
||||
}
|
||||
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
if (pDudeExtraE->at8 && pDudeExtraE->at4 < 10)
|
||||
pDudeExtraE->at4++;
|
||||
else if (pDudeExtraE->at4 >= 10 && pDudeExtraE->at8)
|
||||
{
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleTurn);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
sub_5F15C(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void MoveDodgeUp(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x1d555;
|
||||
}
|
||||
|
||||
static void MoveDodgeDown(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
if (pXSprite->dodgeDir == 0)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x44444;
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFGoto);
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
// Should be dudeInfo[pTarget->type-kDudeBase]
|
||||
int height2 = (pDudeInfo->eyeHeight*pTarget->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int floorZ = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 206:
|
||||
if (nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
sfxPlay3DSound(pSprite, 1408, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFThrow);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 207)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 1408, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFThrow);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sfxPlay3DSound(pSprite, 1408, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
sfxPlay3DSound(pSprite, 1406, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 207)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 1406, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sfxPlay3DSound(pSprite, 1406, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((height2-height > 0x2000 || floorZ-bottom > 0x2000) && nDist < 0x1400 && nDist > 0xa00)
|
||||
{
|
||||
aiPlay3DSound(pSprite, 1400, AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleSwoop);
|
||||
}
|
||||
else if ((height2-height < 0x2000 || floorZ-bottom < 0x2000) && klabs(nDeltaAngle) < 85)
|
||||
aiPlay3DSound(pSprite, 1400, AI_SFX_PRIORITY_1, -1);
|
||||
break;
|
||||
case 207:
|
||||
if (nDist < 0x1800 && nDist > 0xc00 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
sfxPlay3DSound(pSprite, 1457, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleSBlast);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 206)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 1457, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleSBlast);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sfxPlay3DSound(pSprite, 1457, 0, 0);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleSBlast);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 206)
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFSlash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((height2-height > 0x2000 || floorZ-bottom > 0x2000) && nDist < 0x1400 && nDist > 0x800)
|
||||
{
|
||||
if (pSprite->type == 206)
|
||||
aiPlay3DSound(pSprite, 1400, AI_SFX_PRIORITY_1, -1);
|
||||
else
|
||||
aiPlay3DSound(pSprite, 1450, AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &gargoyleSwoop);
|
||||
}
|
||||
else if ((height2-height < 0x2000 || floorZ-bottom < 0x2000) && klabs(nDeltaAngle) < 85)
|
||||
aiPlay3DSound(pSprite, 1450, AI_SFX_PRIORITY_1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &gargoyleFGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void entryFStatue(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[6];
|
||||
actHealDude(pXSprite, pDudeInfo->startHealth, pDudeInfo->startHealth);
|
||||
pSprite->type = 206;
|
||||
}
|
||||
|
||||
static void entrySStatue(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[7];
|
||||
actHealDude(pXSprite, pDudeInfo->startHealth, pDudeInfo->startHealth);
|
||||
pSprite->type = 207;
|
||||
}
|
||||
|
||||
static void MoveForward(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if ((unsigned int)Random(64) < 32 && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void MoveSlow(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 = nAccel>>1;
|
||||
t2 >>= 1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 206:
|
||||
zvel[nSprite] = 0x44444;
|
||||
break;
|
||||
case 207:
|
||||
zvel[nSprite] = 0x35555;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MoveSwoop(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 206:
|
||||
zvel[nSprite] = t1;
|
||||
break;
|
||||
case 207:
|
||||
zvel[nSprite] = t1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MoveFly(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 206:
|
||||
zvel[nSprite] = -t1;
|
||||
break;
|
||||
case 207:
|
||||
zvel[nSprite] = -t1;
|
||||
break;
|
||||
}
|
||||
klabs(zvel[nSprite]);
|
||||
}
|
50
source/blood/src/aigarg.h
Normal file
50
source/blood/src/aigarg.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE gargoyleFIdle;
|
||||
extern AISTATE gargoyleStatueIdle;
|
||||
extern AISTATE gargoyleFChase;
|
||||
extern AISTATE gargoyleFGoto;
|
||||
extern AISTATE gargoyleFSlash;
|
||||
extern AISTATE gargoyleFThrow;
|
||||
extern AISTATE gargoyleSThrow;
|
||||
extern AISTATE gargoyleSBlast;
|
||||
extern AISTATE gargoyleFRecoil;
|
||||
extern AISTATE gargoyleFSearch;
|
||||
extern AISTATE gargoyleFMorph2;
|
||||
extern AISTATE gargoyleFMorph;
|
||||
extern AISTATE gargoyleSMorph2;
|
||||
extern AISTATE gargoyleSMorph;
|
||||
extern AISTATE gargoyleSwoop;
|
||||
extern AISTATE gargoyleFly;
|
||||
extern AISTATE gargoyleTurn;
|
||||
extern AISTATE gargoyleDodgeUp;
|
||||
extern AISTATE gargoyleFDodgeUpRight;
|
||||
extern AISTATE gargoyleFDodgeUpLeft;
|
||||
extern AISTATE gargoyleDodgeDown;
|
||||
extern AISTATE gargoyleFDodgeDownRight;
|
||||
extern AISTATE gargoyleFDodgeDownLeft;
|
||||
extern AISTATE statueFBreakSEQ;
|
||||
extern AISTATE statueSBreakSEQ;
|
587
source/blood/src/aighost.cpp
Normal file
587
source/blood/src/aighost.cpp
Normal file
|
@ -0,0 +1,587 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aighost.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void SlashSeqCallback(int, int);
|
||||
static void ThrowSeqCallback(int, int);
|
||||
static void BlastSeqCallback(int, int);
|
||||
static void thinkTarget(spritetype *, XSPRITE *);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeUp(spritetype *, XSPRITE *);
|
||||
static void MoveDodgeDown(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void MoveForward(spritetype *, XSPRITE *);
|
||||
static void MoveSlow(spritetype *, XSPRITE *);
|
||||
static void MoveSwoop(spritetype *, XSPRITE *);
|
||||
static void MoveFly(spritetype *, XSPRITE *);
|
||||
|
||||
static int nSlashClient = seqRegisterClient(SlashSeqCallback);
|
||||
static int nThrowClient = seqRegisterClient(ThrowSeqCallback);
|
||||
static int nBlastClient = seqRegisterClient(BlastSeqCallback);
|
||||
|
||||
AISTATE ghostIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, thinkTarget, NULL };
|
||||
AISTATE ghostChase = { kAiStateChase, 0, -1, 0, NULL, MoveForward, thinkChase, &ghostIdle };
|
||||
AISTATE ghostGoto = { kAiStateMove, 0, -1, 600, NULL, MoveForward, thinkGoto, &ghostIdle };
|
||||
AISTATE ghostSlash = { kAiStateChase, 6, nSlashClient, 120, NULL, NULL, NULL, &ghostChase };
|
||||
AISTATE ghostThrow = { kAiStateChase, 6, nThrowClient, 120, NULL, NULL, NULL, &ghostChase };
|
||||
AISTATE ghostBlast = { kAiStateChase, 6, nBlastClient, 120, NULL, MoveSlow, NULL, &ghostChase };
|
||||
AISTATE ghostRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &ghostChase };
|
||||
AISTATE ghostTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &ghostChase };
|
||||
AISTATE ghostSearch = { kAiStateSearch, 0, -1, 120, NULL, MoveForward, thinkSearch, &ghostIdle };
|
||||
AISTATE ghostSwoop = { kAiStateOther, 0, -1, 120, NULL, MoveSwoop, thinkChase, &ghostChase };
|
||||
AISTATE ghostFly = { kAiStateMove, 0, -1, 0, NULL, MoveFly, thinkChase, &ghostChase };
|
||||
AISTATE ghostTurn = { kAiStateMove, 0, -1, 120, NULL, aiMoveTurn, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeUp = { kAiStateMove, 0, -1, 60, NULL, MoveDodgeUp, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeUpRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeUpLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeUp, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeDown = { kAiStateMove, 0, -1, 120, NULL, MoveDodgeDown, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeDownRight = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &ghostChase };
|
||||
AISTATE ghostDodgeDownLeft = { kAiStateMove, 0, -1, 90, NULL, MoveDodgeDown, NULL, &ghostChase };
|
||||
|
||||
static void SlashSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2;
|
||||
int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2;
|
||||
int dz = height-height2;
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
sfxPlay3DSound(pSprite, 1406, 0, 0);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_12);
|
||||
int r1 = Random(50);
|
||||
int r2 = Random(50);
|
||||
actFireVector(pSprite, 0, 0, dx+r2, dy-r1, dz, VECTOR_TYPE_12);
|
||||
r1 = Random(50);
|
||||
r2 = Random(50);
|
||||
actFireVector(pSprite, 0, 0, dx-r2, dy+r1, dz, VECTOR_TYPE_12);
|
||||
}
|
||||
|
||||
static void ThrowSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
actFireThing(&sprite[nSprite], 0, 0, gDudeSlope[nXSprite]-7500, 421, 0xeeeee);
|
||||
}
|
||||
|
||||
static void BlastSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
wrand(); // ???
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int height = (pSprite->yrepeat*dudeInfo[pSprite->type-kDudeBase].eyeHeight) << 2;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nDist) = approxDist(dx, dy);
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height;
|
||||
TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa };
|
||||
Aim aim;
|
||||
aim.dx = Cos(pSprite->ang)>>16;
|
||||
aim.dy = Sin(pSprite->ang)>>16;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
int nClosest = 0x7fffffff;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt.at8)
|
||||
{
|
||||
int tz = pSprite2->z-pSprite->z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
if (tz > -0x333)
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
else if (tz < -0x333 && tz > -0xb33)
|
||||
aim.dz = divscale(tz, nDist, 10)+9460;
|
||||
else if (tz < -0xb33 && tz > -0x3000)
|
||||
aim.dz = divscale(tz, nDist, 10)+9460;
|
||||
else if (tz < -0x3000)
|
||||
aim.dz = divscale(tz, nDist, 10)-7500;
|
||||
else
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) || !VanillaMode()) // By NoOne: allow fire missile in non-player targets if not a demo
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 489, 0, 0);
|
||||
actFireMissile(pSprite, 0, 0, aim.dx, aim.dy, aim.dz, 307);
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
if (pDudeExtraE->at8 && pDudeExtraE->at4 < 10)
|
||||
pDudeExtraE->at4++;
|
||||
else if (pDudeExtraE->at4 >= 10 && pDudeExtraE->at8)
|
||||
{
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
aiNewState(pSprite, pXSprite, &ghostTurn);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
return;
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
pDudeExtraE->at4 = 0;
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &ghostSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void MoveDodgeUp(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -0x1d555;
|
||||
}
|
||||
|
||||
static void MoveDodgeDown(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
if (pXSprite->dodgeDir == 0)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int dx = xvel[nSprite];
|
||||
int dy = yvel[nSprite];
|
||||
int t1 = dmulscale30(dx, nCos, dy, nSin);
|
||||
int t2 = dmulscale30(dx, nSin, -dy, nCos);
|
||||
if (pXSprite->dodgeDir > 0)
|
||||
t2 += pDudeInfo->sideSpeed;
|
||||
else
|
||||
t2 -= pDudeInfo->sideSpeed;
|
||||
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = 0x44444;
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ghostGoto);
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ghostSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ghostSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
// Should be dudeInfo[pTarget->type-kDudeBase]
|
||||
int height2 = (pDudeInfo->eyeHeight*pTarget->yrepeat)<<2;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int floorZ = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 210:
|
||||
if (nDist < 0x2000 && nDist > 0x1000 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &ghostBlast);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 210)
|
||||
aiNewState(pSprite, pXSprite, &ghostBlast);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &ghostBlast);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &ghostSlash);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type && sprite[gHitInfo.hitsprite].type != 210)
|
||||
aiNewState(pSprite, pXSprite, &ghostSlash);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &ghostSlash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((height2-height > 0x2000 || floorZ-bottom > 0x2000) && nDist < 0x1400 && nDist > 0x800)
|
||||
{
|
||||
aiPlay3DSound(pSprite, 1600, AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &ghostSwoop);
|
||||
}
|
||||
else if ((height2-height < 0x2000 || floorZ-bottom < 0x2000) && klabs(nDeltaAngle) < 85)
|
||||
aiPlay3DSound(pSprite, 1600, AI_SFX_PRIORITY_1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ghostFly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &ghostGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void MoveForward(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if ((unsigned int)Random(64) < 32 && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void MoveSlow(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 = nAccel>>1;
|
||||
t2 >>= 1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 210:
|
||||
zvel[nSprite] = 0x44444;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MoveSwoop(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 210:
|
||||
zvel[nSprite] = t1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MoveFly(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = pDudeInfo->frontSpeed<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 210:
|
||||
zvel[nSprite] = -t1;
|
||||
break;
|
||||
}
|
||||
}
|
42
source/blood/src/aighost.h
Normal file
42
source/blood/src/aighost.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
extern AISTATE ghostIdle;
|
||||
extern AISTATE ghostChase;
|
||||
extern AISTATE ghostGoto;
|
||||
extern AISTATE ghostSlash;
|
||||
extern AISTATE ghostThrow;
|
||||
extern AISTATE ghostBlast;
|
||||
extern AISTATE ghostRecoil;
|
||||
extern AISTATE ghostTeslaRecoil;
|
||||
extern AISTATE ghostSearch;
|
||||
extern AISTATE ghostSwoop;
|
||||
extern AISTATE ghostFly;
|
||||
extern AISTATE ghostTurn;
|
||||
extern AISTATE ghostDodgeUp;
|
||||
extern AISTATE ghostDodgeUpRight;
|
||||
extern AISTATE ghostDodgeUpLeft;
|
||||
extern AISTATE ghostDodgeDown;
|
||||
extern AISTATE ghostDodgeDownRight;
|
||||
extern AISTATE ghostDodgeDownLeft;
|
415
source/blood/src/aigilbst.cpp
Normal file
415
source/blood/src/aigilbst.cpp
Normal file
|
@ -0,0 +1,415 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aigilbst.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void GillBiteSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void thinkSwimGoto(spritetype *, XSPRITE *);
|
||||
static void thinkSwimChase(spritetype *, XSPRITE *);
|
||||
static void sub_6CB00(spritetype *, XSPRITE *);
|
||||
static void sub_6CD74(spritetype *, XSPRITE *);
|
||||
static void sub_6D03C(spritetype *, XSPRITE *);
|
||||
|
||||
static int nGillBiteClient = seqRegisterClient(GillBiteSeqCallback);
|
||||
|
||||
AISTATE gillBeastIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE gillBeastChase = { kAiStateChase, 9, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE gillBeastDodge = { kAiStateMove, 9, -1, 90, NULL, aiMoveDodge, NULL, &gillBeastChase };
|
||||
AISTATE gillBeastGoto = { kAiStateMove, 9, -1, 600, NULL, aiMoveForward, thinkGoto, &gillBeastIdle };
|
||||
AISTATE gillBeastBite = { kAiStateChase, 6, nGillBiteClient, 120, NULL, NULL, NULL, &gillBeastChase };
|
||||
AISTATE gillBeastSearch = { kAiStateMove, 9, -1, 120, NULL, aiMoveForward, thinkSearch, &gillBeastIdle };
|
||||
AISTATE gillBeastRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &gillBeastDodge };
|
||||
AISTATE gillBeastSwimIdle = { kAiStateIdle, 10, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE gillBeastSwimChase = { kAiStateChase, 10, -1, 0, NULL, sub_6CB00, thinkSwimChase, NULL };
|
||||
AISTATE gillBeastSwimDodge = { kAiStateMove, 10, -1, 90, NULL, aiMoveDodge, NULL, &gillBeastSwimChase };
|
||||
AISTATE gillBeastSwimGoto = { kAiStateMove, 10, -1, 600, NULL, aiMoveForward, thinkSwimGoto, &gillBeastSwimIdle };
|
||||
AISTATE gillBeastSwimSearch = { kAiStateSearch, 10, -1, 120, NULL, aiMoveForward, thinkSearch, &gillBeastSwimIdle };
|
||||
AISTATE gillBeastSwimBite = { kAiStateChase, 7, nGillBiteClient, 0, NULL, NULL, thinkSwimChase, &gillBeastSwimChase };
|
||||
AISTATE gillBeastSwimRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &gillBeastSwimDodge };
|
||||
AISTATE gillBeast13A138 = { kAiStateOther, 10, -1, 120, NULL, sub_6CD74, thinkSwimChase, &gillBeastSwimChase };
|
||||
AISTATE gillBeast13A154 = { kAiStateOther, 10, -1, 0, NULL, sub_6D03C, thinkSwimChase, &gillBeastSwimChase };
|
||||
AISTATE gillBeast13A170 = { kAiStateOther, 10, -1, 120, NULL, NULL, aiMoveTurn, &gillBeastSwimChase };
|
||||
|
||||
static void GillBiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
int dz = pSprite->z-pTarget->z;
|
||||
dx += Random3(2000);
|
||||
dy += Random3(2000);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_8);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_8);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_8);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSearch);
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int nXSprite = sprite[pXSprite->reference].extra;
|
||||
gDudeSlope[nXSprite] = divscale(pTarget->z-pSprite->z, nDist, 10);
|
||||
if (nDist < 921 && klabs(nDeltaAngle) < 28)
|
||||
{
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimBite);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastBite);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimBite);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastBite);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimDodge);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastDodge);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimBite);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastBite);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XSECTOR *pXSector;
|
||||
int nXSector = sector[pSprite->sectnum].extra;
|
||||
if (nXSector > 0)
|
||||
pXSector = &xsector[nXSector];
|
||||
else
|
||||
pXSector = NULL;
|
||||
if (pXSector && pXSector->Underwater)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimGoto);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeastGoto);
|
||||
sfxPlay3DSound(pSprite, 1701, -1, 0);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void thinkSwimGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkSwimChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = pDudeInfo->eyeHeight+pSprite->z;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
int UNUSED(floorZ) = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimBite);
|
||||
else
|
||||
{
|
||||
aiPlay3DSound(pSprite, 1700, AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &gillBeast13A154);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &gillBeast13A154);
|
||||
return;
|
||||
}
|
||||
aiNewState(pSprite, pXSprite, &gillBeastSwimGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void sub_6CB00(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<27)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
return;
|
||||
if (pXSprite->target == -1)
|
||||
pSprite->ang = (pSprite->ang+256)&2047;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Random(64) < 32 && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
if (pXSprite->target == -1)
|
||||
t1 += nAccel;
|
||||
else
|
||||
t1 += nAccel>>2;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
}
|
||||
|
||||
static void sub_6CD74(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<27)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pXSprite->goalAng = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = z2 - z;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x600) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = -dz;
|
||||
}
|
||||
|
||||
static void sub_6D03C(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
int nSprite = pSprite->index;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
int z = pSprite->z + dudeInfo[pSprite->type - kDudeBase].eyeHeight;
|
||||
int z2 = pTarget->z + dudeInfo[pTarget->type - kDudeBase].eyeHeight;
|
||||
int nAng = ((pXSprite->goalAng+1024-pSprite->ang)&2047)-1024;
|
||||
int nTurnRange = (pDudeInfo->angSpeed<<2)>>4;
|
||||
pSprite->ang = (pSprite->ang+ClipRange(nAng, -nTurnRange, nTurnRange))&2047;
|
||||
int nAccel = (pDudeInfo->frontSpeed-(((4-gGameOptions.nDifficulty)<<27)/120)/120)<<2;
|
||||
if (klabs(nAng) > 341)
|
||||
{
|
||||
pSprite->ang = (pSprite->ang+512)&2047;
|
||||
return;
|
||||
}
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int dz = (z2 - z)<<3;
|
||||
int UNUSED(nAngle) = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (Chance(0x4000) && nDist <= 0x400)
|
||||
return;
|
||||
int nCos = Cos(pSprite->ang);
|
||||
int nSin = Sin(pSprite->ang);
|
||||
int vx = xvel[nSprite];
|
||||
int vy = yvel[nSprite];
|
||||
int t1 = dmulscale30(vx, nCos, vy, nSin);
|
||||
int t2 = dmulscale30(vx, nSin, -vy, nCos);
|
||||
t1 += nAccel>>1;
|
||||
xvel[nSprite] = dmulscale30(t1, nCos, t2, nSin);
|
||||
yvel[nSprite] = dmulscale30(t1, nSin, -t2, nCos);
|
||||
zvel[nSprite] = dz;
|
||||
}
|
43
source/blood/src/aigilbst.h
Normal file
43
source/blood/src/aigilbst.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE gillBeastIdle;
|
||||
extern AISTATE gillBeastChase;
|
||||
extern AISTATE gillBeastDodge;
|
||||
extern AISTATE gillBeastGoto;
|
||||
extern AISTATE gillBeastBite;
|
||||
extern AISTATE gillBeastSearch;
|
||||
extern AISTATE gillBeastRecoil;
|
||||
extern AISTATE gillBeastSwimIdle;
|
||||
extern AISTATE gillBeastSwimChase;
|
||||
extern AISTATE gillBeastSwimDodge;
|
||||
extern AISTATE gillBeastSwimGoto;
|
||||
extern AISTATE gillBeastSwimSearch;
|
||||
extern AISTATE gillBeastSwimBite;
|
||||
extern AISTATE gillBeastSwimRecoil;
|
||||
extern AISTATE gillBeast13A138;
|
||||
extern AISTATE gillBeast13A154;
|
||||
extern AISTATE gillBeast13A170;
|
||||
|
138
source/blood/src/aihand.cpp
Normal file
138
source/blood/src/aihand.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aihand.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void HandJumpSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
static int nJumpClient = seqRegisterClient(HandJumpSeqCallback);
|
||||
|
||||
AISTATE handIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE hand13A3B4 = { kAiStateOther, 0, -1, 0, NULL, NULL, NULL, NULL };
|
||||
AISTATE handSearch = { kAiStateMove, 6, -1, 600, NULL, aiMoveForward, thinkSearch, &handIdle };
|
||||
AISTATE handChase = { kAiStateChase, 6, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE handRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &handSearch };
|
||||
AISTATE handGoto = { kAiStateMove, 6, -1, 1800, NULL, aiMoveForward, thinkGoto, &handIdle };
|
||||
AISTATE handJump = { kAiStateChase, 7, nJumpClient, 120, NULL, NULL, NULL, &handChase };
|
||||
|
||||
static void HandJumpSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
if (IsPlayerSprite(pTarget))
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[pTarget->type-kDudePlayer1];
|
||||
if (!pPlayer->at376)
|
||||
{
|
||||
pPlayer->at376 = 1;
|
||||
actPostSprite(pSprite->index, kStatFree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &handSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &handGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &handSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &handSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x233 && klabs(nDeltaAngle) < 85 && gGameOptions.nGameType == 0)
|
||||
aiNewState(pSprite, pXSprite, &handJump);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &handGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
32
source/blood/src/aihand.h
Normal file
32
source/blood/src/aihand.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE handIdle;
|
||||
extern AISTATE hand13A3B4;
|
||||
extern AISTATE handSearch;
|
||||
extern AISTATE handChase;
|
||||
extern AISTATE handRecoil;
|
||||
extern AISTATE handGoto;
|
||||
extern AISTATE handJump;
|
160
source/blood/src/aihound.cpp
Normal file
160
source/blood/src/aihound.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aihound.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BiteSeqCallback(int, int);
|
||||
static void BurnSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(BiteSeqCallback);
|
||||
static int nBurnClient = seqRegisterClient(BurnSeqCallback);
|
||||
|
||||
AISTATE houndIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE houndSearch = { kAiStateMove, 8, -1, 1800, NULL, aiMoveForward, thinkSearch, &houndIdle };
|
||||
AISTATE houndChase = { kAiStateChase, 8, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE houndRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &houndSearch };
|
||||
AISTATE houndTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &houndSearch };
|
||||
AISTATE houndGoto = { kAiStateMove, 8, -1, 600, NULL, aiMoveForward, thinkGoto, &houndIdle };
|
||||
AISTATE houndBite = { kAiStateChase, 6, nBiteClient, 60, NULL, NULL, NULL, &houndChase };
|
||||
AISTATE houndBurn = { kAiStateChase, 7, nBurnClient, 60, NULL, NULL, NULL, &houndChase };
|
||||
|
||||
static void BiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
if (IsPlayerSprite(pTarget) || !VanillaMode()) // allow to hit non-player targets if not a demo
|
||||
actFireVector(pSprite, 0, 0, dx, dy, pTarget->z-pSprite->z, VECTOR_TYPE_15);
|
||||
}
|
||||
|
||||
static void BurnSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
actFireMissile(pSprite, 0, 0, Cos(pSprite->ang)>>16, Sin(pSprite->ang)>>16, 0, 308);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &houndSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &houndGoto);
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &houndSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &houndSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0xb00 && nDist > 0x500 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &houndBurn);
|
||||
else if(nDist < 0x266 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &houndBite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &houndGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
33
source/blood/src/aihound.h
Normal file
33
source/blood/src/aihound.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE houndIdle;
|
||||
extern AISTATE houndSearch;
|
||||
extern AISTATE houndChase;
|
||||
extern AISTATE houndRecoil;
|
||||
extern AISTATE houndTeslaRecoil;
|
||||
extern AISTATE houndGoto;
|
||||
extern AISTATE houndBite;
|
||||
extern AISTATE houndBurn;
|
119
source/blood/src/aiinnoc.cpp
Normal file
119
source/blood/src/aiinnoc.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aiinnoc.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
AISTATE innocentIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE innocentSearch = { kAiStateSearch, 6, -1, 1800, NULL, aiMoveForward, thinkSearch, &innocentIdle };
|
||||
AISTATE innocentChase = { kAiStateChase, 6, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE innocentRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &innocentChase };
|
||||
AISTATE innocentTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &innocentChase };
|
||||
AISTATE innocentGoto = { kAiStateMove, 6, -1, 600, NULL, aiMoveForward, thinkGoto, &innocentIdle };
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &innocentSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &innocentGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &innocentSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget))
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &innocentSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x666 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &innocentIdle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiPlay3DSound(pSprite, 7000+Random(6), AI_SFX_PRIORITY_1, -1);
|
||||
aiNewState(pSprite, pXSprite, &innocentGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
31
source/blood/src/aiinnoc.h
Normal file
31
source/blood/src/aiinnoc.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE innocentIdle;
|
||||
extern AISTATE innocentSearch;
|
||||
extern AISTATE innocentChase;
|
||||
extern AISTATE innocentRecoil;
|
||||
extern AISTATE innocentTeslaRecoil;
|
||||
extern AISTATE innocentGoto;
|
282
source/blood/src/aipod.cpp
Normal file
282
source/blood/src/aipod.cpp
Normal file
|
@ -0,0 +1,282 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aipod.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void sub_6FF08(int, int);
|
||||
static void sub_6FF54(int, int);
|
||||
static void sub_6FFA0(int, int);
|
||||
static void sub_70284(int, int);
|
||||
static void sub_7034C(spritetype *, XSPRITE *);
|
||||
static void sub_70380(spritetype *, XSPRITE *);
|
||||
static void sub_704D8(spritetype *, XSPRITE *);
|
||||
|
||||
static int dword_279B34 = seqRegisterClient(sub_6FFA0);
|
||||
static int dword_279B38 = seqRegisterClient(sub_70284);
|
||||
static int dword_279B3C = seqRegisterClient(sub_6FF08);
|
||||
static int dword_279B40 = seqRegisterClient(sub_6FF54);
|
||||
|
||||
AISTATE podIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE pod13A600 = { kAiStateMove, 7, -1, 3600, NULL, aiMoveTurn, sub_70380, &podSearch };
|
||||
AISTATE podSearch = { kAiStateSearch, 0, -1, 3600, NULL, aiMoveTurn, sub_7034C, &podSearch };
|
||||
AISTATE pod13A638 = { kAiStateChase, 8, dword_279B34, 600, NULL, NULL, NULL, &podChase };
|
||||
AISTATE podRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &podChase };
|
||||
AISTATE podChase = { kAiStateChase, 6, -1, 0, NULL, aiMoveTurn, sub_704D8, NULL };
|
||||
AISTATE tentacleIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE tentacle13A6A8 = { kAiStateOther, 7, dword_279B3C, 0, NULL, NULL, NULL, &tentacle13A6C4 };
|
||||
AISTATE tentacle13A6C4 = { kAiStateOther, -1, -1, 0, NULL, NULL, NULL, &tentacleChase };
|
||||
AISTATE tentacle13A6E0 = { kAiStateOther, 8, dword_279B40, 0, NULL, NULL, NULL, &tentacle13A6FC };
|
||||
AISTATE tentacle13A6FC = { kAiStateOther, -1, -1, 0, NULL, NULL, NULL, &tentacleIdle };
|
||||
AISTATE tentacle13A718 = { kAiStateOther, 8, -1, 3600, NULL, aiMoveTurn, sub_70380, &tentacleSearch };
|
||||
AISTATE tentacleSearch = { kAiStateOther, 0, -1, 3600, NULL, aiMoveTurn, sub_7034C, NULL };
|
||||
AISTATE tentacle13A750 = { kAiStateOther, 6, dword_279B38, 120, NULL, NULL, NULL, &tentacleChase };
|
||||
AISTATE tentacleRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &tentacleChase };
|
||||
AISTATE tentacleChase = { kAiStateChase, 6, -1, 0, NULL, aiMoveTurn, sub_704D8, NULL };
|
||||
|
||||
static void sub_6FF08(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
sfxPlay3DSound(&sprite[nSprite], 2503, -1, 0);
|
||||
}
|
||||
|
||||
static void sub_6FF54(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
sfxPlay3DSound(&sprite[nSprite], 2500, -1, 0);
|
||||
}
|
||||
|
||||
static void sub_6FFA0(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
int x = pTarget->x-pSprite->x;
|
||||
int y = pTarget->y-pSprite->y;
|
||||
int dz = pTarget->z-pSprite->z;
|
||||
x += Random2(1000);
|
||||
y += Random2(1000);
|
||||
int nDist = approxDist(x, y);
|
||||
int nDist2 = nDist / 540;
|
||||
spritetype *pMissile = NULL;
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
dz += 8000;
|
||||
if (pDudeInfo->seeDist*0.1 < nDist)
|
||||
{
|
||||
if (Chance(0x8000))
|
||||
sfxPlay3DSound(pSprite, 2474, -1, 0);
|
||||
else
|
||||
sfxPlay3DSound(pSprite, 2475, -1, 0);
|
||||
pMissile = actFireThing(pSprite, 0, -8000, dz/128-14500, 430, (nDist2<<23)/120);
|
||||
}
|
||||
if (pMissile)
|
||||
seqSpawn(68, 3, pMissile->extra, -1);
|
||||
break;
|
||||
case 223:
|
||||
dz += 8000;
|
||||
if (pDudeInfo->seeDist*0.1 < nDist)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 2454, -1, 0);
|
||||
pMissile = actFireThing(pSprite, 0, -8000, dz/128-14500, 429, (nDist2<<23)/120);
|
||||
}
|
||||
if (pMissile)
|
||||
seqSpawn(22, 3, pMissile->extra, -1);
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
sub_746D4(pSprite, 240);
|
||||
}
|
||||
|
||||
static void sub_70284(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
sfxPlay3DSound(pSprite, 2502, -1, 0);
|
||||
int nDist, nBurn;
|
||||
DAMAGE_TYPE dmgType;
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 222:
|
||||
default:
|
||||
nBurn = 0;
|
||||
dmgType = DAMAGE_TYPE_2;
|
||||
nDist = 50;
|
||||
break;
|
||||
case 224:
|
||||
nBurn = (gGameOptions.nDifficulty*120)>>2;
|
||||
dmgType = DAMAGE_TYPE_3;
|
||||
nDist = 75;
|
||||
break;
|
||||
}
|
||||
sub_2A620(nSprite, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, nDist, 1, 5*(1+gGameOptions.nDifficulty), dmgType, 2, nBurn, 0, 0);
|
||||
}
|
||||
|
||||
static void sub_7034C(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void sub_70380(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
case 223:
|
||||
aiNewState(pSprite, pXSprite, &podSearch);
|
||||
break;
|
||||
case 222:
|
||||
case 224:
|
||||
aiNewState(pSprite, pXSprite, &tentacleSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void sub_704D8(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
case 223:
|
||||
aiNewState(pSprite, pXSprite, &pod13A600);
|
||||
break;
|
||||
case 222:
|
||||
case 224:
|
||||
aiNewState(pSprite, pXSprite, &tentacle13A718);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
case 223:
|
||||
aiNewState(pSprite, pXSprite, &podSearch);
|
||||
break;
|
||||
case 222:
|
||||
case 224:
|
||||
aiNewState(pSprite, pXSprite, &tentacleSearch);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (klabs(nDeltaAngle) < 85 && pTarget->type != 221 && pTarget->type != 223)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
case 223:
|
||||
aiNewState(pSprite, pXSprite, &pod13A638);
|
||||
break;
|
||||
case 222:
|
||||
case 224:
|
||||
aiNewState(pSprite, pXSprite, &tentacle13A750);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 221:
|
||||
case 223:
|
||||
aiNewState(pSprite, pXSprite, &pod13A600);
|
||||
break;
|
||||
case 222:
|
||||
case 224:
|
||||
aiNewState(pSprite, pXSprite, &tentacle13A718);
|
||||
break;
|
||||
}
|
||||
pXSprite->target = -1;
|
||||
}
|
41
source/blood/src/aipod.h
Normal file
41
source/blood/src/aipod.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE podIdle;
|
||||
extern AISTATE pod13A600;
|
||||
extern AISTATE podSearch;
|
||||
extern AISTATE pod13A638;
|
||||
extern AISTATE podRecoil;
|
||||
extern AISTATE podChase;
|
||||
extern AISTATE tentacleIdle;
|
||||
extern AISTATE tentacle13A6A8;
|
||||
extern AISTATE tentacle13A6C4;
|
||||
extern AISTATE tentacle13A6E0;
|
||||
extern AISTATE tentacle13A6FC;
|
||||
extern AISTATE tentacle13A718;
|
||||
extern AISTATE tentacleSearch;
|
||||
extern AISTATE tentacle13A750;
|
||||
extern AISTATE tentacleRecoil;
|
||||
extern AISTATE tentacleChase;
|
135
source/blood/src/airat.cpp
Normal file
135
source/blood/src/airat.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "airat.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void BiteSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(BiteSeqCallback);
|
||||
|
||||
AISTATE ratIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE ratSearch = { kAiStateSearch, 7, -1, 1800, NULL, aiMoveForward, thinkSearch, &ratIdle };
|
||||
AISTATE ratChase = { kAiStateChase, 7, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE ratDodge = { kAiStateMove, 7, -1, 0, NULL, NULL, NULL, &ratChase };
|
||||
AISTATE ratRecoil = { kAiStateRecoil, 7, -1, 0, NULL, NULL, NULL, &ratDodge };
|
||||
AISTATE ratGoto = { kAiStateMove, 7, -1, 600, NULL, aiMoveForward, thinkGoto, &ratIdle };
|
||||
AISTATE ratBite = { kAiStateChase, 6, nBiteClient, 120, NULL, NULL, NULL, &ratChase };
|
||||
|
||||
static void BiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
if (IsPlayerSprite(pTarget))
|
||||
actFireVector(pSprite, 0, 0, dx, dy, pTarget->z-pSprite->z, VECTOR_TYPE_16);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &ratSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ratGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ratSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &ratSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &ratBite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &ratGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
32
source/blood/src/airat.h
Normal file
32
source/blood/src/airat.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE ratIdle;
|
||||
extern AISTATE ratSearch;
|
||||
extern AISTATE ratChase;
|
||||
extern AISTATE ratDodge;
|
||||
extern AISTATE ratRecoil;
|
||||
extern AISTATE ratGoto;
|
||||
extern AISTATE ratBit;
|
290
source/blood/src/aispid.cpp
Normal file
290
source/blood/src/aispid.cpp
Normal file
|
@ -0,0 +1,290 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aispid.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "endgame.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void SpidBiteSeqCallback(int, int);
|
||||
static void SpidJumpSeqCallback(int, int);
|
||||
static void sub_71370(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
|
||||
static int nBiteClient = seqRegisterClient(SpidBiteSeqCallback);
|
||||
static int nJumpClient = seqRegisterClient(SpidJumpSeqCallback);
|
||||
static int dword_279B50 = seqRegisterClient(sub_71370);
|
||||
|
||||
AISTATE spidIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE spidChase = { kAiStateChase, 7, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE spidDodge = { kAiStateMove, 7, -1, 90, NULL, aiMoveDodge, NULL, &spidChase };
|
||||
AISTATE spidGoto = { kAiStateMove, 7, -1, 600, NULL, aiMoveForward, thinkGoto, &spidIdle };
|
||||
AISTATE spidSearch = { kAiStateSearch, 7, -1, 1800, NULL, aiMoveForward, thinkSearch, &spidIdle };
|
||||
AISTATE spidBite = { kAiStateChase, 6, nBiteClient, 60, NULL, NULL, NULL, &spidChase };
|
||||
AISTATE spidJump = { kAiStateChase, 8, nJumpClient, 60, NULL, aiMoveForward, NULL, &spidChase };
|
||||
AISTATE spid13A92C = { kAiStateOther, 0, dword_279B50, 60, NULL, NULL, NULL, &spidIdle };
|
||||
|
||||
static char sub_70D30(XSPRITE *pXDude, int a2, int a3)
|
||||
{
|
||||
dassert(pXDude != NULL);
|
||||
int nDude = pXDude->reference;
|
||||
spritetype *pDude = &sprite[nDude];
|
||||
if (IsPlayerSprite(pDude))
|
||||
{
|
||||
a2 <<= 4;
|
||||
a3 <<= 4;
|
||||
if (IsPlayerSprite(pDude))
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[pDude->type-kDudePlayer1];
|
||||
if (a3 > pPlayer->at36a)
|
||||
{
|
||||
pPlayer->at36a = ClipHigh(pPlayer->at36a+a2, a3);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SpidBiteSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
dx += Random2(2000);
|
||||
dy += Random2(2000);
|
||||
int dz = Random2(2000);
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
if (IsPlayerSprite(pTarget))
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
if (hit == 3)
|
||||
{
|
||||
if (sprite[gHitInfo.hitsprite].type <= kDudePlayer8 && sprite[gHitInfo.hitsprite].type >= kDudePlayer1)
|
||||
{
|
||||
dz += pTarget->z-pSprite->z;
|
||||
if (pTarget->type >= kDudePlayer1 && pTarget->type <= kDudePlayer8)
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[pTarget->type-kDudePlayer1];
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 213:
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
|
||||
if (IsPlayerSprite(pTarget) && !pPlayer->at31a && powerupCheck(pPlayer, 14) <= 0
|
||||
&& Chance(0x4000))
|
||||
powerupActivate(pPlayer, 28);
|
||||
break;
|
||||
case 214:
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
|
||||
if (Chance(0x5000))
|
||||
sub_70D30(pXTarget, 4, 16);
|
||||
break;
|
||||
case 215:
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
|
||||
sub_70D30(pXTarget, 8, 16);
|
||||
break;
|
||||
case 216:
|
||||
{
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
|
||||
dx += Random2(2000);
|
||||
dy += Random2(2000);
|
||||
dz += Random2(2000);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
|
||||
sub_70D30(pXTarget, 8, 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SpidJumpSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int dx = Cos(pSprite->ang)>>16;
|
||||
int dy = Sin(pSprite->ang)>>16;
|
||||
dx += Random2(200);
|
||||
dy += Random2(200);
|
||||
int dz = Random2(200);
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
if (IsPlayerSprite(pTarget))
|
||||
{
|
||||
dz += pTarget->z-pSprite->z;
|
||||
if (pTarget->type >= kDudePlayer1 && pTarget->type <= kDudePlayer8)
|
||||
{
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 213:
|
||||
case 214:
|
||||
case 215:
|
||||
xvel[nSprite] = dx << 16;
|
||||
yvel[nSprite] = dy << 16;
|
||||
zvel[nSprite] = dz << 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sub_71370(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
spritetype *pSpawn = NULL;
|
||||
if (IsPlayerSprite(pTarget) && pDudeExtraE->at4 < 10)
|
||||
{
|
||||
if (nDist < 0x1a00 && nDist > 0x1400 && klabs(pSprite->ang-nAngle) < pDudeInfo->periphery)
|
||||
pSpawn = actSpawnDude(pSprite, 214, pSprite->clipdist, 0);
|
||||
else if (nDist < 0x1400 && nDist > 0xc00 && klabs(pSprite->ang-nAngle) < pDudeInfo->periphery)
|
||||
pSpawn = actSpawnDude(pSprite, 213, pSprite->clipdist, 0);
|
||||
else if (nDist < 0xc00 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
pSpawn = actSpawnDude(pSprite, 213, pSprite->clipdist, 0);
|
||||
if (pSpawn)
|
||||
{
|
||||
pDudeExtraE->at4++;
|
||||
pSpawn->owner = nSprite;
|
||||
gKillMgr.sub_263E0(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &spidSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &spidGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &spidSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &spidSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 214:
|
||||
if (nDist < 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &spidBite);
|
||||
break;
|
||||
case 213:
|
||||
case 215:
|
||||
if (nDist < 0x733 && nDist > 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &spidJump);
|
||||
else if (nDist < 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &spidBite);
|
||||
break;
|
||||
case 216:
|
||||
if (nDist < 0x733 && nDist > 0x399 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &spidJump);
|
||||
else if (Chance(0x8000))
|
||||
aiNewState(pSprite, pXSprite, &spid13A92C);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &spidGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
33
source/blood/src/aispid.h
Normal file
33
source/blood/src/aispid.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE spidIdle;
|
||||
extern AISTATE spidChase;
|
||||
extern AISTATE spidDodge;
|
||||
extern AISTATE spidGoto;
|
||||
extern AISTATE spidSearch;
|
||||
extern AISTATE spidBite;
|
||||
extern AISTATE spidJump;
|
||||
extern AISTATE spid13A92C;
|
357
source/blood/src/aitchern.cpp
Normal file
357
source/blood/src/aitchern.cpp
Normal file
|
@ -0,0 +1,357 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aitchern.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void sub_71A90(int, int);
|
||||
static void sub_71BD4(int, int);
|
||||
static void sub_720AC(int, int);
|
||||
static void sub_72580(spritetype *, XSPRITE *);
|
||||
static void sub_725A4(spritetype *, XSPRITE *);
|
||||
static void sub_72850(spritetype *, XSPRITE *);
|
||||
static void sub_72934(spritetype *, XSPRITE *);
|
||||
|
||||
static int dword_279B54 = seqRegisterClient(sub_71BD4);
|
||||
static int dword_279B58 = seqRegisterClient(sub_720AC);
|
||||
static int dword_279B5C = seqRegisterClient(sub_71A90);
|
||||
|
||||
AISTATE tchernobogIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, sub_725A4, NULL };
|
||||
AISTATE tchernobogSearch = { kAiStateSearch, 8, -1, 1800, NULL, aiMoveForward, sub_72580, &tchernobogIdle };
|
||||
AISTATE tchernobogChase = { kAiStateChase, 8, -1, 0, NULL, aiMoveForward, sub_72934, NULL };
|
||||
AISTATE tchernobogRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &tchernobogSearch };
|
||||
AISTATE tcherno13A9B8 = { kAiStateMove, 8, -1, 600, NULL, aiMoveForward, sub_72850, &tchernobogIdle };
|
||||
AISTATE tcherno13A9D4 = { kAiStateMove, 6, dword_279B54, 60, NULL, NULL, NULL, &tchernobogChase };
|
||||
AISTATE tcherno13A9F0 = { kAiStateChase, 6, dword_279B58, 60, NULL, NULL, NULL, &tchernobogChase };
|
||||
AISTATE tcherno13AA0C = { kAiStateChase, 7, dword_279B5C, 60, NULL, NULL, NULL, &tchernobogChase };
|
||||
AISTATE tcherno13AA28 = { kAiStateChase, 8, -1, 60, NULL, aiMoveTurn, NULL, &tchernobogChase };
|
||||
|
||||
static void sub_71A90(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int nTarget = pTarget->index;
|
||||
int nOwner = actSpriteIdToOwnerId(nSprite);
|
||||
if (pXTarget->burnTime == 0)
|
||||
evPost(nTarget, 3, 0, CALLBACK_ID_0);
|
||||
actBurnSprite(nOwner, pXTarget, 40);
|
||||
if (Chance(0x6000))
|
||||
aiNewState(pSprite, pXSprite, &tcherno13A9D4);
|
||||
}
|
||||
|
||||
static void sub_71BD4(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
int height = pSprite->yrepeat*pDudeInfo->eyeHeight;
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height;
|
||||
TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x100000 };
|
||||
Aim aim;
|
||||
aim.dx = Cos(pSprite->ang)>>16;
|
||||
aim.dy = Sin(pSprite->ang)>>16;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
int nClosest = 0x7fffffff;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt.at8)
|
||||
{
|
||||
int tz = pSprite2->z-pSprite->z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
actFireMissile(pSprite, -350, 0, aim.dx, aim.dy, aim.dz, 314);
|
||||
actFireMissile(pSprite, 350, 0, aim.dx, aim.dy, aim.dz, 314);
|
||||
}
|
||||
|
||||
static void sub_720AC(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
int height = pSprite->yrepeat*pDudeInfo->eyeHeight;
|
||||
int ax, ay, az;
|
||||
ax = Cos(pSprite->ang)>>16;
|
||||
ay = Sin(pSprite->ang)>>16;
|
||||
int x = pSprite->x;
|
||||
int y = pSprite->y;
|
||||
int z = height;
|
||||
TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x100000 };
|
||||
Aim aim;
|
||||
aim.dx = ax;
|
||||
aim.dy = ay;
|
||||
aim.dz = gDudeSlope[nXSprite];
|
||||
int nClosest = 0x7fffffff;
|
||||
az = 0;
|
||||
for (short nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2])
|
||||
{
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
if (pSprite == pSprite2 || !(pSprite2->hitag&8))
|
||||
continue;
|
||||
int x2 = pSprite2->x;
|
||||
int y2 = pSprite2->y;
|
||||
int z2 = pSprite2->z;
|
||||
int nDist = approxDist(x2-x, y2-y);
|
||||
if (nDist == 0 || nDist > 0x2800)
|
||||
continue;
|
||||
if (tt.at10)
|
||||
{
|
||||
int t = divscale(nDist, tt.at10, 12);
|
||||
x2 += (xvel[nSprite2]*t)>>12;
|
||||
y2 += (yvel[nSprite2]*t)>>12;
|
||||
z2 += (zvel[nSprite2]*t)>>8;
|
||||
}
|
||||
int tx = x+mulscale30(Cos(pSprite->ang), nDist);
|
||||
int ty = y+mulscale30(Sin(pSprite->ang), nDist);
|
||||
int tz = z+mulscale(gDudeSlope[nXSprite], nDist, 10);
|
||||
int tsr = mulscale(9460, nDist, 10);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite2, &top, &bottom);
|
||||
if (tz-tsr > bottom || tz+tsr < top)
|
||||
continue;
|
||||
int dx = (tx-x2)>>4;
|
||||
int dy = (ty-y2)>>4;
|
||||
int dz = (tz-z2)>>8;
|
||||
int nDist2 = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (nDist2 < nClosest)
|
||||
{
|
||||
int nAngle = getangle(x2-x, y2-y);
|
||||
int nDeltaAngle = ((nAngle-pSprite->ang+1024)&2047)-1024;
|
||||
if (klabs(nDeltaAngle) <= tt.at8)
|
||||
{
|
||||
int tz = pSprite2->z-pSprite->z;
|
||||
if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum))
|
||||
{
|
||||
nClosest = nDist2;
|
||||
aim.dx = Cos(nAngle)>>16;
|
||||
aim.dy = Sin(nAngle)>>16;
|
||||
aim.dz = divscale(tz, nDist, 10);
|
||||
}
|
||||
else
|
||||
aim.dz = tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
actFireMissile(pSprite, 350, 0, aim.dx, aim.dy, -aim.dz, 314);
|
||||
actFireMissile(pSprite, -350, 0, ax, ay, az, 314);
|
||||
}
|
||||
|
||||
static void sub_72580(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void sub_725A4(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
|
||||
if (pDudeExtraE->at4 && pDudeExtraE->at0 < 10)
|
||||
pDudeExtraE->at0++;
|
||||
else if (pDudeExtraE->at0 >= 10 && pDudeExtraE->at4)
|
||||
{
|
||||
pXSprite->goalAng += 256;
|
||||
POINT3D *pTarget = &baseSprite[pSprite->index];
|
||||
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
|
||||
aiNewState(pSprite, pXSprite, &tcherno13AA28);
|
||||
return;
|
||||
}
|
||||
if (Chance(pDudeInfo->alertChance))
|
||||
{
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
if (pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
pDudeExtraE->at0 = 0;
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
pDudeExtraE->at0 = 0;
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sub_72850(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &tchernobogSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void sub_72934(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tcherno13A9B8);
|
||||
return;
|
||||
}
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
return;
|
||||
//dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (!(pXSprite->target >= 0 && pXSprite->target < kMaxSprites))
|
||||
return;
|
||||
//dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tchernobogSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &tchernobogSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x1f00 && nDist > 0xd00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &tcherno13AA0C);
|
||||
else if (nDist < 0xd00 && nDist > 0xb00 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &tcherno13A9D4);
|
||||
else if (nDist < 0xb00 && nDist > 0x500 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &tcherno13A9F0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &tcherno13A9B8);
|
||||
pXSprite->target = -1;
|
||||
}
|
34
source/blood/src/aitchern.h
Normal file
34
source/blood/src/aitchern.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE tchernobogIdle;
|
||||
extern AISTATE tchernobogSearch;
|
||||
extern AISTATE tchernobogChase;
|
||||
extern AISTATE tchernobogRecoil;
|
||||
extern AISTATE tcherno13A9B8;
|
||||
extern AISTATE tcherno13A9D4;
|
||||
extern AISTATE tcherno13A9F0;
|
||||
extern AISTATE tcherno13AA0C;
|
||||
extern AISTATE tcherno13AA28;
|
1309
source/blood/src/aiunicult.cpp
Normal file
1309
source/blood/src/aiunicult.cpp
Normal file
File diff suppressed because it is too large
Load diff
75
source/blood/src/aiunicult.h
Normal file
75
source/blood/src/aiunicult.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
Copyright (C) NoOne
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
#include "eventq.h"
|
||||
|
||||
extern AISTATE GDXGenDudeIdleL;
|
||||
extern AISTATE GDXGenDudeIdleW;
|
||||
extern AISTATE GDXGenDudeSearchL;
|
||||
extern AISTATE GDXGenDudeSearchW;
|
||||
extern AISTATE GDXGenDudeGotoL;
|
||||
extern AISTATE GDXGenDudeGotoW;
|
||||
extern AISTATE GDXGenDudeDodgeL;
|
||||
extern AISTATE GDXGenDudeDodgeD;
|
||||
extern AISTATE GDXGenDudeDodgeW;
|
||||
extern AISTATE GDXGenDudeDodgeDmgL;
|
||||
extern AISTATE GDXGenDudeDodgeDmgD;
|
||||
extern AISTATE GDXGenDudeDodgeDmgW;
|
||||
extern AISTATE GDXGenDudeChaseL;
|
||||
extern AISTATE GDXGenDudeChaseD;
|
||||
extern AISTATE GDXGenDudeChaseW;
|
||||
extern AISTATE GDXGenDudeFireL;
|
||||
extern AISTATE GDXGenDudeFireD;
|
||||
extern AISTATE GDXGenDudeFireW;
|
||||
extern AISTATE GDXGenDudeFire2L;
|
||||
extern AISTATE GDXGenDudeFire2D;
|
||||
extern AISTATE GDXGenDudeFire2W;
|
||||
extern AISTATE GDXGenDudeRecoilL;
|
||||
extern AISTATE GDXGenDudeRecoilD;
|
||||
extern AISTATE GDXGenDudeRecoilW;
|
||||
extern AISTATE GDGenDudeThrow;
|
||||
extern AISTATE GDGenDudeThrow2;
|
||||
extern AISTATE GDXGenDudePunch;
|
||||
extern AISTATE GDXGenDudeRTesla;
|
||||
extern AISTATE GDXGenDudeProne;
|
||||
extern AISTATE GDXGenDudeTurn;
|
||||
|
||||
XSPRITE* getNextIncarnation(XSPRITE* pXSprite);
|
||||
void killDudeLeech(spritetype* pLeech);
|
||||
void removeLeech(spritetype* pLeech, bool delSprite = true);
|
||||
void removeDudeStuff(spritetype* pSprite);
|
||||
spritetype* leechIsDropped(spritetype* pSprite);
|
||||
bool spriteIsUnderwater(spritetype* pSprite, bool oldWay);
|
||||
bool sfxPlayGDXGenDudeSound(spritetype* pSprite, int mode, int data);
|
||||
void aiGenDudeMoveForward(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
int getGenDudeMoveSpeed(spritetype* pSprite, int which, bool mul, bool shift);
|
||||
bool TargetNearThing(spritetype* pSprite, int thingType);
|
||||
int checkAttackState(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
bool doExplosion(spritetype* pSprite, int nType);
|
||||
void dudeLeechOperate(spritetype* pSprite, XSPRITE* pXSprite, EVENT a3);
|
||||
int getDodgeChance(spritetype* pSprite);
|
||||
int getRecoilChance(spritetype* pSprite);
|
||||
bool dudeIsMelee(XSPRITE* pXSprite);
|
||||
void updateTargetOfSlaves(spritetype* pSprite);
|
281
source/blood/src/aizomba.cpp
Normal file
281
source/blood/src/aizomba.cpp
Normal file
|
@ -0,0 +1,281 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aizomba.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void HackSeqCallback(int, int);
|
||||
static void StandSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *, XSPRITE *);
|
||||
static void thinkGoto(spritetype *, XSPRITE *);
|
||||
static void thinkChase(spritetype *, XSPRITE *);
|
||||
static void thinkPonder(spritetype *, XSPRITE *);
|
||||
static void myThinkTarget(spritetype *, XSPRITE *);
|
||||
static void myThinkSearch(spritetype *, XSPRITE *);
|
||||
static void entryEZombie(spritetype *, XSPRITE *);
|
||||
static void entryAIdle(spritetype *, XSPRITE *);
|
||||
static void entryEStand(spritetype *, XSPRITE *);
|
||||
|
||||
static int nHackClient = seqRegisterClient(HackSeqCallback);
|
||||
static int nStandClient = seqRegisterClient(StandSeqCallback);
|
||||
|
||||
AISTATE zombieAIdle = { kAiStateIdle, 0, -1, 0, entryAIdle, NULL, aiThinkTarget, NULL };
|
||||
AISTATE zombieAChase = { kAiStateChase, 8, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE zombieAPonder = { kAiStateOther, 0, -1, 0, NULL, aiMoveTurn, thinkPonder, NULL };
|
||||
AISTATE zombieAGoto = { kAiStateMove, 8, -1, 1800, NULL, aiMoveForward, thinkGoto, &zombieAIdle };
|
||||
AISTATE zombieAHack = { kAiStateChase, 6, nHackClient, 80, NULL, NULL, NULL, &zombieAPonder };
|
||||
AISTATE zombieASearch = { kAiStateSearch, 8, -1, 1800, NULL, aiMoveForward, thinkSearch, &zombieAIdle };
|
||||
AISTATE zombieARecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &zombieAPonder };
|
||||
AISTATE zombieATeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &zombieAPonder };
|
||||
AISTATE zombieARecoil2 = { kAiStateRecoil, 1, -1, 360, NULL, NULL, NULL, &zombieAStand };
|
||||
AISTATE zombieAStand = { kAiStateMove, 11, nStandClient, 0, NULL, NULL, NULL, &zombieAPonder };
|
||||
AISTATE zombieEIdle = { kAiStateIdle, 12, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE zombieEUp2 = { kAiStateMove, 0, -1, 1, entryEZombie, NULL, NULL, &zombieASearch };
|
||||
AISTATE zombieEUp = { kAiStateMove, 9, -1, 180, entryEStand, NULL, NULL, &zombieEUp2 };
|
||||
AISTATE zombie2Idle = { kAiStateIdle, 0, -1, 0, entryAIdle, NULL, myThinkTarget, NULL };
|
||||
AISTATE zombie2Search = { kAiStateSearch, 8, -1, 1800, NULL, NULL, myThinkSearch, &zombie2Idle };
|
||||
AISTATE zombieSIdle = { kAiStateIdle, 10, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE zombie13AC2C = { kAiStateOther, 11, nStandClient, 0, entryEZombie, NULL, NULL, &zombieAPonder };
|
||||
|
||||
static void HackSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int tx = pXSprite->targetX-pSprite->x;
|
||||
int ty = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nDist) = approxDist(tx, ty);
|
||||
int nAngle = getangle(tx, ty);
|
||||
int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2;
|
||||
int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2;
|
||||
int dz = height-height2;
|
||||
int dx = Cos(nAngle)>>16;
|
||||
int dy = Sin(nAngle)>>16;
|
||||
sfxPlay3DSound(pSprite, 1101, 1, 0);
|
||||
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_10);
|
||||
}
|
||||
|
||||
static void StandSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
sfxPlay3DSound(&sprite[nSprite], 1102, -1, 0);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
sub_5F15C(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 921 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &zombieASearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieASearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieASearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && (powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0 || powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 31) > 0))
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieAGoto);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
aiNewState(pSprite, pXSprite, &zombieAHack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &zombieAGoto);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void thinkPonder(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieASearch);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieASearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && (powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0 || powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 31) > 0))
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieAGoto);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x400)
|
||||
{
|
||||
if (klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 1101, 1, 0);
|
||||
aiNewState(pSprite, pXSprite, &zombieAHack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &zombieAChase);
|
||||
}
|
||||
|
||||
static void myThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[p];
|
||||
int nOwner = (pSprite->owner & 0x1000) ? (pSprite->owner&0xfff) : -1;
|
||||
if (nOwner == pPlayer->at5b || pPlayer->pXSprite->health == 0 || powerupCheck(pPlayer, 13) > 0)
|
||||
continue;
|
||||
int x = pPlayer->pSprite->x;
|
||||
int y = pPlayer->pSprite->y;
|
||||
int z = pPlayer->pSprite->z;
|
||||
int nSector = pPlayer->pSprite->sectnum;
|
||||
int dx = x-pSprite->x;
|
||||
int dy = y-pSprite->y;
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist > pDudeInfo->seeDist && nDist > pDudeInfo->hearDist)
|
||||
continue;
|
||||
if (!cansee(x, y, z, nSector, pSprite->x, pSprite->y, pSprite->z-((pDudeInfo->eyeHeight*pSprite->yrepeat)<<2), pSprite->sectnum))
|
||||
continue;
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pPlayer->at5b);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else if (nDist < pDudeInfo->hearDist)
|
||||
{
|
||||
aiSetTarget(pXSprite, x, y, z);
|
||||
aiActivateDude(pSprite, pXSprite);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void myThinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
myThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void entryEZombie(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pXSprite);
|
||||
pSprite->type = 203;
|
||||
pSprite->hitag |= 1;
|
||||
}
|
||||
|
||||
static void entryAIdle(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pSprite);
|
||||
pXSprite->target = -1;
|
||||
}
|
||||
|
||||
static void entryEStand(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
sfxPlay3DSound(pSprite, 1100, -1, 0);
|
||||
pSprite->ang = getangle(pXSprite->targetX-pSprite->x, pXSprite->targetY-pSprite->y);
|
||||
}
|
42
source/blood/src/aizomba.h
Normal file
42
source/blood/src/aizomba.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE zombieAIdle;
|
||||
extern AISTATE zombieAChase;
|
||||
extern AISTATE zombieAPonder;
|
||||
extern AISTATE zombieAGoto;
|
||||
extern AISTATE zombieAHack;
|
||||
extern AISTATE zombieASearch;
|
||||
extern AISTATE zombieARecoil;
|
||||
extern AISTATE zombieATeslaRecoil;
|
||||
extern AISTATE zombieARecoil2;
|
||||
extern AISTATE zombieAStand;
|
||||
extern AISTATE zombieEIdle;
|
||||
extern AISTATE zombieEUp2;
|
||||
extern AISTATE zombieEUp;
|
||||
extern AISTATE zombie2Idle;
|
||||
extern AISTATE zombie2Search;
|
||||
extern AISTATE zombieSIdle;
|
||||
extern AISTATE zombie13AC2C;
|
230
source/blood/src/aizombf.cpp
Normal file
230
source/blood/src/aizombf.cpp
Normal file
|
@ -0,0 +1,230 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "pragmas.h"
|
||||
#include "mmulti.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "aizombf.h"
|
||||
#include "blood.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "trig.h"
|
||||
|
||||
static void HackSeqCallback(int, int);
|
||||
static void PukeSeqCallback(int, int);
|
||||
static void ThrowSeqCallback(int, int);
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite);
|
||||
|
||||
static int nHackClient = seqRegisterClient(HackSeqCallback);
|
||||
static int nPukeClient = seqRegisterClient(PukeSeqCallback);
|
||||
static int nThrowClient = seqRegisterClient(ThrowSeqCallback);
|
||||
|
||||
AISTATE zombieFIdle = { kAiStateIdle, 0, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE zombieFChase = { kAiStateChase, 8, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE zombieFGoto = { kAiStateMove, 8, -1, 600, NULL, aiMoveForward, thinkGoto, &zombieFIdle };
|
||||
AISTATE zombieFDodge = { kAiStateMove, 8, -1, 0, NULL, aiMoveDodge, thinkChase, &zombieFChase };
|
||||
AISTATE zombieFHack = { kAiStateChase, 6, nHackClient, 120, NULL, NULL, NULL, &zombieFChase };
|
||||
AISTATE zombieFPuke = { kAiStateChase, 9, nPukeClient, 120, NULL, NULL, NULL, &zombieFChase };
|
||||
AISTATE zombieFThrow = { kAiStateChase, 6, nThrowClient, 120, NULL, NULL, NULL, &zombieFChase };
|
||||
AISTATE zombieFSearch = { kAiStateSearch, 8, -1, 1800, NULL, aiMoveForward, thinkSearch, &zombieFIdle };
|
||||
AISTATE zombieFRecoil = { kAiStateRecoil, 5, -1, 0, NULL, NULL, NULL, &zombieFChase };
|
||||
AISTATE zombieFTeslaRecoil = { kAiStateRecoil, 4, -1, 0, NULL, NULL, NULL, &zombieFChase };
|
||||
|
||||
static void HackSeqCallback(int, int nXSprite)
|
||||
{
|
||||
if (nXSprite <= 0 || nXSprite >= kMaxXSprites)
|
||||
return;
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
if (nXSprite < 0 || nXSprite >= kMaxSprites)
|
||||
return;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (pSprite->type != 204)
|
||||
return;
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat);
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int height2 = (pDudeInfoT->eyeHeight*pTarget->yrepeat);
|
||||
actFireVector(pSprite, 0, 0, Cos(pSprite->ang)>>16, Sin(pSprite->ang)>>16, height-height2, VECTOR_TYPE_11);
|
||||
}
|
||||
|
||||
static void PukeSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
DUDEINFO *pDudeInfoT = &dudeInfo[pTarget->type-kDudeBase];
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat);
|
||||
int height2 = (pDudeInfoT->eyeHeight*pTarget->yrepeat);
|
||||
int tx = pXSprite->targetX-pSprite->x;
|
||||
int ty = pXSprite->targetY-pSprite->y;
|
||||
int UNUSED(nDist) = approxDist(tx, ty);
|
||||
int nAngle = getangle(tx, ty);
|
||||
int dx = Cos(nAngle)>>16;
|
||||
int dy = Sin(nAngle)>>16;
|
||||
sfxPlay3DSound(pSprite, 1203, 1, 0);
|
||||
actFireMissile(pSprite, 0, -(height-height2), dx, dy, 0, 309);
|
||||
}
|
||||
|
||||
static void ThrowSeqCallback(int, int nXSprite)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int nSprite = pXSprite->reference;
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
actFireMissile(pSprite, 0, -dudeInfo[pSprite->type-kDudeBase].eyeHeight, Cos(pSprite->ang)>>16, Sin(pSprite->ang)>>16, 0, 300);
|
||||
}
|
||||
|
||||
static void thinkSearch(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
int dx = pXSprite->targetX-pSprite->x;
|
||||
int dy = pXSprite->targetY-pSprite->y;
|
||||
int nAngle = getangle(dx, dy);
|
||||
int nDist = approxDist(dx, dy);
|
||||
aiChooseDirection(pSprite, pXSprite, nAngle);
|
||||
if (nDist < 512 && klabs(pSprite->ang - nAngle) < pDudeInfo->periphery)
|
||||
aiNewState(pSprite, pXSprite, &zombieFSearch);
|
||||
aiThinkTarget(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
||||
{
|
||||
if (pXSprite->target == -1)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieFGoto);
|
||||
return;
|
||||
}
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget = &xsprite[pTarget->extra];
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
|
||||
if (pXTarget->health == 0)
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieFSearch);
|
||||
return;
|
||||
}
|
||||
if (IsPlayerSprite(pTarget) && (powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 13) > 0 || powerupCheck(&gPlayer[pTarget->type-kDudePlayer1], 31) > 0))
|
||||
{
|
||||
aiNewState(pSprite, pXSprite, &zombieFSearch);
|
||||
return;
|
||||
}
|
||||
int nDist = approxDist(dx, dy);
|
||||
if (nDist <= pDudeInfo->seeDist)
|
||||
{
|
||||
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
|
||||
int height = (pDudeInfo->eyeHeight*pSprite->yrepeat)<<2;
|
||||
if (cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pSprite->x, pSprite->y, pSprite->z - height, pSprite->sectnum))
|
||||
{
|
||||
if (klabs(nDeltaAngle) <= pDudeInfo->periphery)
|
||||
{
|
||||
aiSetTarget(pXSprite, pXSprite->target);
|
||||
if (nDist < 0x1400 && nDist > 0xe00 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &zombieFThrow);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
aiNewState(pSprite, pXSprite, &zombieFThrow);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &zombieFDodge);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &zombieFThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x1400 && nDist > 0x600 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &zombieFPuke);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
aiNewState(pSprite, pXSprite, &zombieFPuke);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &zombieFDodge);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &zombieFPuke);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nDist < 0x400 && klabs(nDeltaAngle) < 85)
|
||||
{
|
||||
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
|
||||
switch (hit)
|
||||
{
|
||||
case -1:
|
||||
aiNewState(pSprite, pXSprite, &zombieFHack);
|
||||
break;
|
||||
case 3:
|
||||
if (pSprite->type != sprite[gHitInfo.hitsprite].type)
|
||||
aiNewState(pSprite, pXSprite, &zombieFHack);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &zombieFDodge);
|
||||
break;
|
||||
default:
|
||||
aiNewState(pSprite, pXSprite, &zombieFHack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNewState(pSprite, pXSprite, &zombieFSearch);
|
||||
pXSprite->target = -1;
|
||||
}
|
35
source/blood/src/aizombf.h
Normal file
35
source/blood/src/aizombf.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "ai.h"
|
||||
|
||||
extern AISTATE zombieFIdle;
|
||||
extern AISTATE zombieFChase;
|
||||
extern AISTATE zombieFGoto;
|
||||
extern AISTATE zombieFDodge;
|
||||
extern AISTATE zombieFHack;
|
||||
extern AISTATE zombieFPuke;
|
||||
extern AISTATE zombieFThrow;
|
||||
extern AISTATE zombieFSearch;
|
||||
extern AISTATE zombieFRecoil;
|
||||
extern AISTATE zombieFTeslaRecoil;
|
158
source/blood/src/asound.cpp
Normal file
158
source/blood/src/asound.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "build.h"
|
||||
#include "fx_man.h"
|
||||
#include "common_game.h"
|
||||
#include "blood.h"
|
||||
#include "config.h"
|
||||
#include "db.h"
|
||||
#include "player.h"
|
||||
#include "resource.h"
|
||||
#include "sound.h"
|
||||
|
||||
#define kMaxAmbChannel 64
|
||||
|
||||
struct AMB_CHANNEL
|
||||
{
|
||||
int at0;
|
||||
int at4;
|
||||
int at8;
|
||||
DICTNODE *atc;
|
||||
char *at10;
|
||||
int at14;
|
||||
int at18;
|
||||
};
|
||||
|
||||
AMB_CHANNEL ambChannels[kMaxAmbChannel];
|
||||
int nAmbChannels = 0;
|
||||
|
||||
void ambProcess(void)
|
||||
{
|
||||
if (!SoundToggle)
|
||||
return;
|
||||
for (int nSprite = headspritestat[12]; nSprite >= 0; nSprite = nextspritestat[nSprite])
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (pSprite->owner < 0 || pSprite->owner >= kMaxAmbChannel)
|
||||
continue;
|
||||
int nXSprite = pSprite->extra;
|
||||
if (nXSprite > 0 && nXSprite < kMaxXSprites)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
if (pXSprite->state)
|
||||
{
|
||||
int dx = pSprite->x-gMe->pSprite->x;
|
||||
int dy = pSprite->y-gMe->pSprite->y;
|
||||
int dz = pSprite->z-gMe->pSprite->z;
|
||||
dx >>= 4;
|
||||
dy >>= 4;
|
||||
dz >>= 8;
|
||||
int nDist = ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
int vs = mulscale16(pXSprite->data4, pXSprite->busy);
|
||||
ambChannels[pSprite->owner].at4 += ClipRange(scale(nDist, pXSprite->data1, pXSprite->data2, vs, 0), 0, vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
AMB_CHANNEL *pChannel = ambChannels;
|
||||
for (int i = 0; i < nAmbChannels; i++, pChannel++)
|
||||
{
|
||||
if (pChannel->at0 > 0)
|
||||
FX_SetPan(pChannel->at0, pChannel->at4, pChannel->at4, pChannel->at4);
|
||||
else
|
||||
{
|
||||
int end = ClipLow(pChannel->at14-1, 0);
|
||||
pChannel->at0 = FX_PlayLoopedRaw(pChannel->at10, pChannel->at14, pChannel->at10, pChannel->at10+end, sndGetRate(pChannel->at18), 0,
|
||||
pChannel->at4, pChannel->at4, pChannel->at4, pChannel->at4, 1.f, (intptr_t)&pChannel->at0);
|
||||
}
|
||||
pChannel->at4 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ambKillAll(void)
|
||||
{
|
||||
AMB_CHANNEL *pChannel = ambChannels;
|
||||
for (int i = 0; i < nAmbChannels; i++, pChannel++)
|
||||
{
|
||||
if (pChannel->at0 > 0)
|
||||
{
|
||||
FX_EndLooping(pChannel->at0);
|
||||
FX_StopSound(pChannel->at0);
|
||||
}
|
||||
if (pChannel->atc)
|
||||
{
|
||||
gSoundRes.Unlock(pChannel->atc);
|
||||
pChannel->atc = NULL;
|
||||
}
|
||||
}
|
||||
nAmbChannels = 0;
|
||||
}
|
||||
|
||||
void ambInit(void)
|
||||
{
|
||||
ambKillAll();
|
||||
memset(ambChannels, 0, sizeof(ambChannels));
|
||||
for (int nSprite = headspritestat[12]; nSprite >= 0; nSprite = nextspritestat[nSprite])
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nXSprite = pSprite->extra;
|
||||
if (nXSprite > 0 && nXSprite < kMaxXSprites)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
if (pXSprite->data1 < pXSprite->data2)
|
||||
{
|
||||
int i;
|
||||
AMB_CHANNEL *pChannel = ambChannels;
|
||||
for (i = 0; i < nAmbChannels; i++, pChannel++)
|
||||
if (pXSprite->data3 == pChannel->at8)
|
||||
break;
|
||||
if (i == nAmbChannels)
|
||||
{
|
||||
if (i >= kMaxAmbChannel)
|
||||
{
|
||||
pSprite->owner = -1;
|
||||
continue;
|
||||
}
|
||||
int nSFX = pXSprite->data3;
|
||||
DICTNODE *pSFXNode = gSoundRes.Lookup(nSFX, "SFX");
|
||||
if (!pSFXNode)
|
||||
ThrowError("Missing sound #%d used in ambient sound generator %d\n", nSFX);
|
||||
SFX *pSFX = (SFX*)gSoundRes.Load(pSFXNode);
|
||||
DICTNODE *pRAWNode = gSoundRes.Lookup(pSFX->rawName, "RAW");
|
||||
if (!pRAWNode)
|
||||
ThrowError("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX);
|
||||
if (pRAWNode->size > 0)
|
||||
{
|
||||
pChannel->at14 = pRAWNode->size;
|
||||
pChannel->at8 = nSFX;
|
||||
pChannel->atc = pRAWNode;
|
||||
pChannel->at14 = pRAWNode->size;
|
||||
pChannel->at10 = (char*)gSoundRes.Lock(pRAWNode);
|
||||
pChannel->at18 = pSFX->format;
|
||||
nAmbChannels++;
|
||||
}
|
||||
}
|
||||
pSprite->owner = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
source/blood/src/asound.h
Normal file
27
source/blood/src/asound.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
void ambProcess(void);
|
||||
void ambKillAll(void);
|
||||
void ambInit(void);
|
2438
source/blood/src/blood.cpp
Normal file
2438
source/blood/src/blood.cpp
Normal file
File diff suppressed because it is too large
Load diff
249
source/blood/src/blood.h
Normal file
249
source/blood/src/blood.h
Normal file
|
@ -0,0 +1,249 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "levels.h"
|
||||
#include "resource.h"
|
||||
|
||||
#define TILTBUFFER 4078
|
||||
|
||||
#define kExplodeMax 8
|
||||
#define kDudeBase 200
|
||||
#define kDudePlayer1 231
|
||||
#define kDudePlayer8 238
|
||||
#define kDudeMax 260
|
||||
#define kMissileBase 300
|
||||
#define kMissileMax 318
|
||||
#define kThingBase 400
|
||||
#define kThingMax 436
|
||||
|
||||
#define kMaxPowerUps 51
|
||||
|
||||
#define kStatRespawn 8
|
||||
#define kStatMarker 10
|
||||
#define kStatGDXDudeTargetChanger 20
|
||||
#define kStatFree 1024
|
||||
|
||||
#define kLensSize 80
|
||||
#define kViewEffectMax 19
|
||||
|
||||
#define kNoTile -1
|
||||
|
||||
|
||||
// defined by NoOne:
|
||||
// -------------------------------
|
||||
#define kMaxPAL 5
|
||||
|
||||
#define kWeaponItemBase 40
|
||||
#define kItemMax 151
|
||||
|
||||
// marker sprite types
|
||||
#define kMarkerSPStart 1
|
||||
#define kMarkerMPStart 2
|
||||
#define kMarkerOff 3
|
||||
#define kMarkerOn 4
|
||||
#define kMarkerAxis 5
|
||||
#define kMarkerLowLink 6
|
||||
#define kMarkerUpLink 7
|
||||
#define kMarkerWarpDest 8
|
||||
#define kMarkerUpWater 9
|
||||
#define kMarkerLowWater 10
|
||||
#define kMarkerUpStack 11
|
||||
#define kMarkerLowStack 12
|
||||
#define kMarkerUpGoo 13
|
||||
#define kMarkerLowGoo 14
|
||||
#define kMarkerPath 15
|
||||
|
||||
// sprite cstat
|
||||
#define kSprBlock 0x0001
|
||||
#define kSprTrans 0x0002
|
||||
#define kSprFlipX 0x0004
|
||||
#define kSprFlipY 0x0008
|
||||
#define kSprFace 0x0000
|
||||
#define kSprWall 0x0010
|
||||
#define kSprFloor 0x0020
|
||||
#define kSprSpin 0x0030
|
||||
#define kSprRMask 0x0030
|
||||
#define kSprOneSided 0x0040
|
||||
#define kSprOriginAlign 0x0080
|
||||
#define kSprHitscan 0x0100
|
||||
#define kSprTransR 0x0200
|
||||
#define kSprPushable 0x1000
|
||||
#define kSprMoveMask 0x6000
|
||||
#define kSprMoveNone 0x0000
|
||||
#define kSprMoveForward 0x2000
|
||||
#define kSprMoveFloor 0x2000
|
||||
#define kSprMoveReverse 0x4000
|
||||
#define kSprMoveCeiling 0x4000
|
||||
#define kSprInvisible 0x8000
|
||||
|
||||
// sprite attributes
|
||||
#define kHitagMovePhys 0x0001 // affected by movement physics
|
||||
#define kHitagGravityPhys 0x0002 // affected by gravity
|
||||
#define kHitagFalling 0x0004 // currently in z-motion
|
||||
#define kHitagAutoAim 0x0008
|
||||
#define kHitagRespawn 0x0010
|
||||
#define kHitagFree 0x0020
|
||||
#define kHitagSmoke 0x0100
|
||||
#define kHitagExtBit 0x8000 // NoOne's extension bit(Note: it's bit 0 in editor!)
|
||||
|
||||
// sector types
|
||||
#define kSecBase 600
|
||||
#define kSecZMotion kSectorBase
|
||||
#define kSecZSprite 602
|
||||
#define kSecWarp 603
|
||||
#define kSecTeleport 604
|
||||
#define kSecPath 612
|
||||
#define kSecRotateStep 613
|
||||
#define kSecSlideMarked 614
|
||||
#define kSecRotateMarked 615
|
||||
#define kSecSlide 616
|
||||
#define kSecRotate 617
|
||||
#define kSecDamage 618
|
||||
#define kSecCounter 619
|
||||
#define kSecMax 620
|
||||
|
||||
// switch types
|
||||
#define kSwitchBase 20
|
||||
#define kSwitchToggle 20
|
||||
#define kSwitchOneWay 21
|
||||
#define kSwitchCombo 22
|
||||
#define kSwitchPadlock 23
|
||||
#define kSwitchMax 24
|
||||
|
||||
// projectile types
|
||||
#define kProjectileEctoSkull 307
|
||||
|
||||
// custom level end
|
||||
#define kGDXChannelEndLevelCustom 6
|
||||
|
||||
// GDX types
|
||||
#define kGDXTypeBase 24
|
||||
#define kGDXCustomDudeSpawn 24
|
||||
#define kGDXRandomTX 25
|
||||
#define kGDXSequentialTX 26
|
||||
#define kGDXSeqSpawner 27
|
||||
#define kGDXObjPropertiesChanger 28
|
||||
#define kGDXObjPicnumChanger 29
|
||||
#define kGDXObjSizeChanger 31
|
||||
#define kGDXDudeTargetChanger 33
|
||||
#define kGDXSectorFXChanger 34
|
||||
#define kGDXObjDataChanger 35
|
||||
#define kGDXSpriteDamager 36
|
||||
#define kGDXObjDataAccumulator 37
|
||||
#define kGDXEffectSpawner 38
|
||||
#define kGDXWindGenerator 39
|
||||
|
||||
#define kGDXThingTNTProx 433 // detects only players
|
||||
#define kGDXThingThrowableRock 434 // does small damage if hits target
|
||||
#define kGDXThingCustomDudeLifeLeech 435 // the same as normal, except it aims in specified target
|
||||
#define kGDXDudeUniversalCultist 254
|
||||
#define kGDXGenDudeBurning 255
|
||||
|
||||
#define kGDXItemMapLevel 150 // once picked up, draws whole minimap
|
||||
|
||||
// ai state types
|
||||
#define kAiStateOther -1
|
||||
#define kAiStateIdle 0
|
||||
#define kAiStateGenIdle 1
|
||||
#define kAiStateMove 2
|
||||
#define kAiStateSearch 3
|
||||
#define kAiStateChase 4
|
||||
#define kAiStateRecoil 5
|
||||
|
||||
|
||||
#define kAng5 28
|
||||
#define kAng15 85
|
||||
#define kAng30 170
|
||||
#define kAng45 256
|
||||
#define kAng60 341
|
||||
#define kAng90 512
|
||||
#define kAng120 682
|
||||
#define kAng180 1024
|
||||
#define kAng360 2048
|
||||
|
||||
|
||||
// -------------------------------
|
||||
|
||||
struct INIDESCRIPTION {
|
||||
const char *pzName;
|
||||
const char *pzFilename;
|
||||
const char **pzArts;
|
||||
int nArts;
|
||||
};
|
||||
|
||||
struct INICHAIN {
|
||||
INICHAIN *pNext;
|
||||
char zName[BMAX_PATH];
|
||||
INIDESCRIPTION *pDescription;
|
||||
};
|
||||
|
||||
extern INICHAIN *pINIChain;
|
||||
extern INICHAIN const*pINISelected;
|
||||
|
||||
typedef struct {
|
||||
int32_t usejoystick;
|
||||
int32_t usemouse;
|
||||
int32_t fullscreen;
|
||||
int32_t xdim;
|
||||
int32_t ydim;
|
||||
int32_t bpp;
|
||||
int32_t forcesetup;
|
||||
int32_t noautoload;
|
||||
} ud_setup_t;
|
||||
|
||||
enum INPUT_MODE {
|
||||
INPUT_MODE_0 = 0,
|
||||
INPUT_MODE_1,
|
||||
INPUT_MODE_2,
|
||||
INPUT_MODE_3,
|
||||
};
|
||||
|
||||
extern Resource gSysRes, gGuiRes;
|
||||
extern INPUT_MODE gInputMode;
|
||||
extern ud_setup_t gSetup;
|
||||
extern char SetupFilename[BMAX_PATH];
|
||||
extern int32_t gNoSetup;
|
||||
extern short BloodVersion;
|
||||
extern int gNetPlayers;
|
||||
extern bool gRestartGame;
|
||||
#define GAMEUPDATEAVGTIMENUMSAMPLES 100
|
||||
extern double g_gameUpdateTime, g_gameUpdateAndDrawTime;
|
||||
extern double g_gameUpdateAvgTime;
|
||||
extern int blood_globalflags;
|
||||
extern bool bVanilla;
|
||||
extern int gMusicPrevLoadedEpisode;
|
||||
extern int gMusicPrevLoadedLevel;
|
||||
|
||||
extern int gFrameClock;
|
||||
|
||||
void QuitGame(void);
|
||||
void PreloadCache(void);
|
||||
void StartLevel(GAMEOPTIONS *gameOptions);
|
||||
void ProcessFrame(void);
|
||||
void ScanINIFiles(void);
|
||||
bool LoadArtFile(const char *pzFile);
|
||||
void LoadExtraArts(void);
|
||||
bool DemoRecordStatus(void);
|
||||
bool VanillaMode(void);
|
||||
bool fileExistsRFF(int id, const char* ext);
|
731
source/blood/src/callback.cpp
Normal file
731
source/blood/src/callback.cpp
Normal file
|
@ -0,0 +1,731 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include "build.h"
|
||||
#include "common_game.h"
|
||||
|
||||
#include "actor.h"
|
||||
#include "ai.h"
|
||||
#include "blood.h"
|
||||
#include "callback.h"
|
||||
#include "config.h"
|
||||
#include "db.h"
|
||||
#include "dude.h"
|
||||
#include "eventq.h"
|
||||
#include "fx.h"
|
||||
#include "gameutil.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "seq.h"
|
||||
#include "sfx.h"
|
||||
#include "sound.h"
|
||||
#include "trig.h"
|
||||
#include "triggers.h"
|
||||
#include "view.h"
|
||||
|
||||
|
||||
void sub_74C20(int nSprite) // 7
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX = gFX.fxSpawn(FX_15, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x10000);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x10000);
|
||||
zvel[pFX->index] = zvel[nSprite] - Random(0x1aaaa);
|
||||
}
|
||||
evPost(nSprite, 3, 3, CALLBACK_ID_7);
|
||||
}
|
||||
|
||||
void sub_74D04(int nSprite) // 15
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX = gFX.fxSpawn(FX_49, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x1aaaa);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x1aaaa);
|
||||
zvel[pFX->index] = zvel[nSprite] - Random(0x1aaaa);
|
||||
}
|
||||
evPost(nSprite, 3, 3, CALLBACK_ID_15);
|
||||
}
|
||||
|
||||
void FinishHim(int nSprite) // 13
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nXSprite = pSprite->extra;
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
if (playerSeqPlaying(&gPlayer[pSprite->type-kDudePlayer1], 16) && pXSprite->target == gMe->at5b)
|
||||
sndStartSample(3313, -1, 1, 0);
|
||||
}
|
||||
|
||||
void FlameLick(int nSprite) // 0
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nXSprite = pSprite->extra;
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int nDist = (pSprite->xrepeat*(tilesiz[pSprite->picnum].x/2))>>3;
|
||||
int nAngle = Random(2048);
|
||||
int dx = mulscale30(nDist, Cos(nAngle));
|
||||
int dy = mulscale30(nDist, Sin(nAngle));
|
||||
int x = pSprite->x + dx;
|
||||
int y = pSprite->y + dy;
|
||||
int z = bottom-Random(bottom-top);
|
||||
spritetype *pFX = gFX.fxSpawn(FX_32, pSprite->sectnum, x, y, z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(-dx);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(-dy);
|
||||
zvel[pFX->index] = zvel[nSprite] - Random(0x1aaaa);
|
||||
}
|
||||
}
|
||||
if (pXSprite->burnTime > 0)
|
||||
evPost(nSprite, 3, 5, CALLBACK_ID_0);
|
||||
}
|
||||
|
||||
void Remove(int nSprite) // 1
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
evKill(nSprite, 3);
|
||||
if (pSprite->extra > 0)
|
||||
seqKill(3, pSprite->extra);
|
||||
sfxKill3DSound(pSprite, 0, -1);
|
||||
DeleteSprite(nSprite);
|
||||
}
|
||||
|
||||
void FlareBurst(int nSprite) // 2
|
||||
{
|
||||
dassert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nAngle = getangle(xvel[nSprite], yvel[nSprite]);
|
||||
int nRadius = 0x55555;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
spritetype *pSpawn = actSpawnSprite(pSprite, 5);
|
||||
pSpawn->picnum = 2424;
|
||||
pSpawn->shade = -128;
|
||||
pSpawn->xrepeat = pSpawn->yrepeat = 32;
|
||||
pSpawn->type = 303;
|
||||
pSpawn->clipdist = 2;
|
||||
pSpawn->owner = pSprite->owner;
|
||||
int nAngle2 = (i<<11)/8;
|
||||
int dx = 0;
|
||||
int dy = mulscale30r(nRadius, Sin(nAngle2));
|
||||
int dz = mulscale30r(nRadius, -Cos(nAngle2));
|
||||
if (i&1)
|
||||
{
|
||||
dy >>= 1;
|
||||
dz >>= 1;
|
||||
}
|
||||
RotateVector(&dx, &dy, nAngle);
|
||||
xvel[pSpawn->index] += dx;
|
||||
yvel[pSpawn->index] += dy;
|
||||
zvel[pSpawn->index] += dz;
|
||||
evPost(pSpawn->index, 3, 960, CALLBACK_ID_3);
|
||||
}
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
}
|
||||
|
||||
void FlareSpark(int nSprite) // 3
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX = gFX.fxSpawn(FX_28, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x1aaaa);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x1aaaa);
|
||||
zvel[pFX->index] = zvel[nSprite] - Random(0x1aaaa);
|
||||
}
|
||||
evPost(nSprite, 3, 4, CALLBACK_ID_3);
|
||||
}
|
||||
|
||||
void FlareSparkLite(int nSprite) // 4
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX = gFX.fxSpawn(FX_28, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x1aaaa);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x1aaaa);
|
||||
zvel[pFX->index] = zvel[nSprite] - Random(0x1aaaa);
|
||||
}
|
||||
evPost(nSprite, 3, 12, CALLBACK_ID_4);
|
||||
}
|
||||
|
||||
void ZombieSpurt(int nSprite) // 5
|
||||
{
|
||||
dassert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nXSprite = pSprite->extra;
|
||||
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
spritetype *pFX = gFX.fxSpawn(FX_27, pSprite->sectnum, pSprite->x, pSprite->y, top, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x11111);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x11111);
|
||||
zvel[pFX->index] = zvel[nSprite] - 0x6aaaa;
|
||||
}
|
||||
if (pXSprite->data1 > 0)
|
||||
{
|
||||
evPost(nSprite, 3, 4, CALLBACK_ID_5);
|
||||
pXSprite->data1 -= 4;
|
||||
}
|
||||
else if (pXSprite->data2 > 0)
|
||||
{
|
||||
evPost(nSprite, 3, 60, CALLBACK_ID_5);
|
||||
pXSprite->data1 = 40;
|
||||
pXSprite->data2--;
|
||||
}
|
||||
}
|
||||
|
||||
void BloodSpurt(int nSprite) // 6
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX = gFX.fxSpawn(FX_27, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
pFX->ang = 0;
|
||||
xvel[pFX->index] = xvel[nSprite]>>8;
|
||||
yvel[pFX->index] = yvel[nSprite]>>8;
|
||||
zvel[pFX->index] = zvel[nSprite]>>8;
|
||||
}
|
||||
evPost(nSprite, 3, 6, CALLBACK_ID_6);
|
||||
}
|
||||
|
||||
void DynPuff(int nSprite) // 8
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (zvel[nSprite])
|
||||
{
|
||||
int nDist = (pSprite->xrepeat*(tilesiz[pSprite->picnum].x/2))>>2;
|
||||
int x = pSprite->x + mulscale30(nDist, Cos(pSprite->ang-512));
|
||||
int y = pSprite->y + mulscale30(nDist, Sin(pSprite->ang-512));
|
||||
int z = pSprite->z;
|
||||
spritetype *pFX = gFX.fxSpawn(FX_7, pSprite->sectnum, x, y, z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite];
|
||||
yvel[pFX->index] = yvel[nSprite];
|
||||
zvel[pFX->index] = zvel[nSprite];
|
||||
}
|
||||
}
|
||||
evPost(nSprite, 3, 12, CALLBACK_ID_8);
|
||||
}
|
||||
|
||||
void Respawn(int nSprite) // 9
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nXSprite = pSprite->extra;
|
||||
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
if (pSprite->statnum != 8 && pSprite->statnum != 4)
|
||||
ThrowError("Sprite %d is not on Respawn or Thing list\n", nSprite);
|
||||
if (!(pSprite->hitag&16))
|
||||
ThrowError("Sprite %d does not have the respawn attribute\n", nSprite);
|
||||
switch (pXSprite->respawnPending)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
int nTime = mulscale16(actGetRespawnTime(pSprite), 0x4000);
|
||||
pXSprite->respawnPending = 2;
|
||||
evPost(nSprite, 3, nTime, CALLBACK_ID_9);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
int nTime = mulscale16(actGetRespawnTime(pSprite), 0x2000);
|
||||
pXSprite->respawnPending = 3;
|
||||
evPost(nSprite, 3, nTime, CALLBACK_ID_9);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
dassert(pSprite->owner != kStatRespawn);
|
||||
dassert(pSprite->owner >= 0 && pSprite->owner < kMaxStatus);
|
||||
ChangeSpriteStat(nSprite, pSprite->owner);
|
||||
pSprite->type = pSprite->zvel;
|
||||
pSprite->owner = -1;
|
||||
pSprite->hitag &= ~16;
|
||||
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
||||
pXSprite->respawnPending = 0;
|
||||
pXSprite->burnTime = 0;
|
||||
pXSprite->isTriggered = 0;
|
||||
if (pSprite->type >= kDudeBase && pSprite->type < kDudeMax)
|
||||
{
|
||||
int nType = pSprite->type-kDudeBase;
|
||||
pSprite->x = baseSprite[nSprite].x;
|
||||
pSprite->y = baseSprite[nSprite].y;
|
||||
pSprite->z = baseSprite[nSprite].z;
|
||||
pSprite->cstat |= 0x1101;
|
||||
pSprite->clipdist = dudeInfo[nType].clipdist;
|
||||
pXSprite->health = dudeInfo[nType].startHealth<<4;
|
||||
if (gSysRes.Lookup(dudeInfo[nType].seqStartID, "SEQ"))
|
||||
seqSpawn(dudeInfo[nType].seqStartID, 3, pSprite->extra, -1);
|
||||
aiInitSprite(pSprite);
|
||||
pXSprite->key = 0;
|
||||
}
|
||||
if (pSprite->type == 400)
|
||||
{
|
||||
pSprite->cstat |= 257;
|
||||
pSprite->cstat &= (unsigned short)~32768;
|
||||
}
|
||||
gFX.fxSpawn(FX_29, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
sfxPlay3DSound(pSprite, 350, -1, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ThrowError("Unexpected respawnPending value = %d", pXSprite->respawnPending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerBubble(int nSprite) // 10
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (IsPlayerSprite(pSprite))
|
||||
{
|
||||
PLAYER *pPlayer = &gPlayer[pSprite->type-kDudePlayer1];
|
||||
dassert(pPlayer != NULL);
|
||||
if (!pPlayer->at302)
|
||||
return;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
for (int i = 0; i < (pPlayer->at302>>6); i++)
|
||||
{
|
||||
int nDist = (pSprite->xrepeat*(tilesiz[pSprite->picnum].x/2))>>2;
|
||||
int nAngle = Random(2048);
|
||||
int x = pSprite->x + mulscale30(nDist, Cos(nAngle));
|
||||
int y = pSprite->y + mulscale30(nDist, Sin(nAngle));
|
||||
int z = bottom-Random(bottom-top);
|
||||
spritetype *pFX = gFX.fxSpawn((FX_ID)(FX_23+Random(3)), pSprite->sectnum, x, y, z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x1aaaa);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x1aaaa);
|
||||
zvel[pFX->index] = zvel[nSprite] + Random2(0x1aaaa);
|
||||
}
|
||||
}
|
||||
evPost(nSprite, 3, 4, CALLBACK_ID_10);
|
||||
}
|
||||
}
|
||||
|
||||
void EnemyBubble(int nSprite) // 11
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
for (int i = 0; i < (klabs(zvel[nSprite])>>18); i++)
|
||||
{
|
||||
int nDist = (pSprite->xrepeat*(tilesiz[pSprite->picnum].x/2))>>2;
|
||||
int nAngle = Random(2048);
|
||||
int x = pSprite->x + mulscale30(nDist, Cos(nAngle));
|
||||
int y = pSprite->y + mulscale30(nDist, Sin(nAngle));
|
||||
int z = bottom-Random(bottom-top);
|
||||
spritetype *pFX = gFX.fxSpawn((FX_ID)(FX_23+Random(3)), pSprite->sectnum, x, y, z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
xvel[pFX->index] = xvel[nSprite] + Random2(0x1aaaa);
|
||||
yvel[pFX->index] = yvel[nSprite] + Random2(0x1aaaa);
|
||||
zvel[pFX->index] = zvel[nSprite] + Random2(0x1aaaa);
|
||||
}
|
||||
}
|
||||
evPost(nSprite, 3, 4, CALLBACK_ID_11);
|
||||
}
|
||||
|
||||
void CounterCheck(int nSector) // 12
|
||||
{
|
||||
dassert(nSector >= 0 && nSector < kMaxSectors);
|
||||
sectortype *pSector = §or[nSector];
|
||||
// By NoOne: edits for counter sector new features.
|
||||
// remove check below, so every sector can be counter if command 12 (this callback) received.
|
||||
//if (pSector->lotag != 619) return;
|
||||
int nXSprite = pSector->extra;
|
||||
if (nXSprite > 0)
|
||||
{
|
||||
XSECTOR *pXSector = &xsector[nXSprite];
|
||||
int nReq = pXSector->waitTimeA;
|
||||
int nType = pXSector->data;
|
||||
if (nType && nReq)
|
||||
{
|
||||
int nCount = 0;
|
||||
for (int nSprite = headspritesect[nSector]; nSprite >= 0; nSprite = nextspritesect[nSprite])
|
||||
{
|
||||
if (sprite[nSprite].type == nType)
|
||||
nCount++;
|
||||
}
|
||||
if (nCount >= nReq)
|
||||
{
|
||||
|
||||
//pXSector->waitTimeA = 0; //do not reset necessary objects counter to zero
|
||||
trTriggerSector(nSector, pXSector, 1);
|
||||
pXSector->locked = 1; //lock sector, so it can be opened again later
|
||||
}
|
||||
else
|
||||
evPost(nSector, 6, 5, CALLBACK_ID_12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sub_76140(int nSprite) // 14
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int ceilZ, ceilHit, floorZ, floorHit;
|
||||
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
pSprite->z += floorZ-bottom;
|
||||
int nAngle = Random(2048);
|
||||
int nDist = Random(16)<<4;
|
||||
int x = pSprite->x+mulscale28(nDist, Cos(nAngle));
|
||||
int y = pSprite->y+mulscale28(nDist, Sin(nAngle));
|
||||
gFX.fxSpawn(FX_48, pSprite->sectnum, x, y, pSprite->z, 0);
|
||||
if (pSprite->ang == 1024)
|
||||
{
|
||||
int nChannel = 28+(pSprite->index&2);
|
||||
dassert(nChannel < 32);
|
||||
sfxPlay3DSound(pSprite, 385, nChannel, 1);
|
||||
}
|
||||
if (Chance(0x5000))
|
||||
{
|
||||
spritetype *pFX = gFX.fxSpawn(FX_36, pSprite->sectnum, x, y, floorZ-64, 0);
|
||||
if (pFX)
|
||||
pFX->ang = nAngle;
|
||||
}
|
||||
gFX.sub_73FFC(nSprite);
|
||||
}
|
||||
|
||||
void sub_7632C(spritetype *pSprite)
|
||||
{
|
||||
xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0;
|
||||
if (pSprite->extra > 0)
|
||||
seqKill(3, pSprite->extra);
|
||||
sfxKill3DSound(pSprite, -1, -1);
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
pSprite->picnum = 2465;
|
||||
break;
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
pSprite->picnum = 2464;
|
||||
break;
|
||||
}
|
||||
pSprite->type = 51;
|
||||
pSprite->xrepeat = pSprite->yrepeat = 10;
|
||||
}
|
||||
|
||||
int dword_13B32C[] = { 608, 609, 611 };
|
||||
int dword_13B338[] = { 610, 612 };
|
||||
|
||||
void sub_763BC(int nSprite) // 16
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int ceilZ, ceilHit, floorZ, floorHit;
|
||||
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
pSprite->z += floorZ-bottom;
|
||||
int zv = zvel[nSprite]-velFloor[pSprite->sectnum];
|
||||
if (zv > 0)
|
||||
{
|
||||
actFloorBounceVector((int*)&xvel[nSprite], (int*)&yvel[nSprite], &zv, pSprite->sectnum, 0x9000);
|
||||
zvel[nSprite] = zv;
|
||||
if (velFloor[pSprite->sectnum] == 0 && klabs(zvel[nSprite]) < 0x20000)
|
||||
{
|
||||
sub_7632C(pSprite);
|
||||
return;
|
||||
}
|
||||
int nChannel = 28+(pSprite->index&2);
|
||||
dassert(nChannel < 32);
|
||||
if (pSprite->type >= 37 && pSprite->type <= 39)
|
||||
{
|
||||
Random(3);
|
||||
sfxPlay3DSound(pSprite, 608+Random(2), nChannel, 1);
|
||||
}
|
||||
else
|
||||
sfxPlay3DSound(pSprite, dword_13B338[Random(2)], nChannel, 1);
|
||||
}
|
||||
else if (zvel[nSprite] == 0)
|
||||
sub_7632C(pSprite);
|
||||
}
|
||||
|
||||
void sub_765B8(int nSprite) // 17
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (pSprite->owner >= 0 && pSprite->owner < kMaxSprites)
|
||||
{
|
||||
spritetype *pOwner = &sprite[pSprite->owner];
|
||||
XSPRITE *pXOwner = &xsprite[pOwner->extra];
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case 147:
|
||||
trTriggerSprite(pOwner->index, pXOwner, 1);
|
||||
sndStartSample(8003, 255, 2, 0);
|
||||
viewSetMessage("Blue Flag returned to base.");
|
||||
break;
|
||||
case 148:
|
||||
trTriggerSprite(pOwner->index, pXOwner, 1);
|
||||
sndStartSample(8002, 255, 2, 0);
|
||||
viewSetMessage("Red Flag returned to base.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
evPost(pSprite->index, 3, 0, CALLBACK_ID_1);
|
||||
}
|
||||
|
||||
void sub_766B8(int nSprite) // 19
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int ceilZ, ceilHit, floorZ, floorHit;
|
||||
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0);
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
pSprite->z += floorZ-bottom;
|
||||
int nAngle = Random(2048);
|
||||
int nDist = Random(16)<<4;
|
||||
int x = pSprite->x+mulscale28(nDist, Cos(nAngle));
|
||||
int y = pSprite->y+mulscale28(nDist, Sin(nAngle));
|
||||
if (pSprite->ang == 1024)
|
||||
{
|
||||
int nChannel = 28+(pSprite->index&2);
|
||||
dassert(nChannel < 32);
|
||||
sfxPlay3DSound(pSprite, 385, nChannel, 1);
|
||||
}
|
||||
spritetype *pFX = NULL;
|
||||
if (pSprite->type == 53 || pSprite->type == 430)
|
||||
{
|
||||
if (Chance(0x500) || pSprite->type == 430)
|
||||
pFX = gFX.fxSpawn(FX_55, pSprite->sectnum, x, y, floorZ-64, 0);
|
||||
if (pFX)
|
||||
pFX->ang = nAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFX = gFX.fxSpawn(FX_32, pSprite->sectnum, x, y, floorZ-64, 0);
|
||||
if (pFX)
|
||||
pFX->ang = nAngle;
|
||||
}
|
||||
gFX.sub_73FFC(nSprite);
|
||||
}
|
||||
|
||||
void sub_768E8(int nSprite) // 18
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
spritetype *pFX;
|
||||
if (pSprite->type == 53)
|
||||
pFX = gFX.fxSpawn(FX_53, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
else
|
||||
pFX = gFX.fxSpawn(FX_54, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0);
|
||||
if (pFX)
|
||||
{
|
||||
pFX->ang = 0;
|
||||
xvel[pFX->index] = xvel[nSprite]>>8;
|
||||
yvel[pFX->index] = yvel[nSprite]>>8;
|
||||
zvel[pFX->index] = zvel[nSprite]>>8;
|
||||
}
|
||||
evPost(nSprite, 3, 6, CALLBACK_ID_18);
|
||||
}
|
||||
|
||||
void sub_769B4(int nSprite) // 19
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (pSprite->statnum == 4 && !(pSprite->hitag & 32)) {
|
||||
switch (pSprite->lotag) {
|
||||
case 431:
|
||||
case kGDXThingCustomDudeLifeLeech:
|
||||
xsprite[pSprite->extra].stateTimer = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sub_76A08(spritetype *pSprite, spritetype *pSprite2, PLAYER *pPlayer)
|
||||
{
|
||||
int top, bottom;
|
||||
int nSprite = pSprite->index;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
pSprite->x = pSprite2->x;
|
||||
pSprite->y = pSprite2->y;
|
||||
pSprite->z = sector[pSprite2->sectnum].floorz-(bottom-pSprite->z);
|
||||
pSprite->ang = pSprite2->ang;
|
||||
ChangeSpriteSect(nSprite, pSprite2->sectnum);
|
||||
sfxPlay3DSound(pSprite2, 201, -1, 0);
|
||||
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
||||
viewBackupSpriteLoc(nSprite, pSprite);
|
||||
if (pPlayer)
|
||||
{
|
||||
playerResetInertia(pPlayer);
|
||||
pPlayer->at6b = pPlayer->at73 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sub_76B78(int nSprite)
|
||||
{
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
int nOwner = actSpriteOwnerToSpriteId(pSprite);
|
||||
if (nOwner < 0 || nOwner >= kMaxSprites)
|
||||
{
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
return;
|
||||
}
|
||||
spritetype *pOwner = &sprite[nOwner];
|
||||
PLAYER *pPlayer;
|
||||
if (IsPlayerSprite(pOwner))
|
||||
pPlayer = &gPlayer[pOwner->type-kDudePlayer1];
|
||||
else
|
||||
pPlayer = NULL;
|
||||
if (!pPlayer)
|
||||
{
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
return;
|
||||
}
|
||||
pSprite->ang = getangle(pOwner->x-pSprite->x, pOwner->y-pSprite->y);
|
||||
int nXSprite = pSprite->extra;
|
||||
if (nXSprite > 0)
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
if (pXSprite->data1 == 0)
|
||||
{
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
return;
|
||||
}
|
||||
int nSprite2, nNextSprite;
|
||||
for (nSprite2 = headspritestat[6]; nSprite2 >= 0; nSprite2 = nNextSprite)
|
||||
{
|
||||
nNextSprite = nextspritestat[nSprite2];
|
||||
if (nOwner == nSprite2)
|
||||
continue;
|
||||
spritetype *pSprite2 = &sprite[nSprite2];
|
||||
int nXSprite2 = pSprite2->extra;
|
||||
if (nXSprite2 > 0 && nXSprite2 < kMaxXSprites)
|
||||
{
|
||||
XSPRITE *pXSprite2 = &xsprite[nXSprite2];
|
||||
PLAYER *pPlayer2;
|
||||
if (IsPlayerSprite(pSprite2))
|
||||
pPlayer2 = &gPlayer[pSprite2->type-kDudePlayer1];
|
||||
else
|
||||
pPlayer2 = NULL;
|
||||
if (pXSprite2->health > 0 && (pPlayer2 || pXSprite2->key == 0))
|
||||
{
|
||||
if (pPlayer2)
|
||||
{
|
||||
if (gGameOptions.nGameType == 1)
|
||||
continue;
|
||||
if (gGameOptions.nGameType == 3 && pPlayer->at2ea == pPlayer2->at2ea)
|
||||
continue;
|
||||
int t = 0x8000/ClipLow(gNetPlayers-1, 1);
|
||||
if (!powerupCheck(pPlayer2, 14))
|
||||
t += ((3200-pPlayer2->at33e[2])<<15)/3200;
|
||||
if (Chance(t) || nNextSprite < 0)
|
||||
{
|
||||
int nDmg = actDamageSprite(nOwner, pSprite2, DAMAGE_TYPE_5, pXSprite->data1<<4);
|
||||
pXSprite->data1 = ClipLow(pXSprite->data1-nDmg, 0);
|
||||
sub_76A08(pSprite2, pSprite, pPlayer2);
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int vd = 0x2666;
|
||||
switch (pSprite2->type)
|
||||
{
|
||||
case 218:
|
||||
case 219:
|
||||
case 220:
|
||||
case 250:
|
||||
case 251:
|
||||
vd = 0x147;
|
||||
break;
|
||||
case 205:
|
||||
case 221:
|
||||
case 222:
|
||||
case 223:
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
case 228:
|
||||
case 229:
|
||||
case 239:
|
||||
case 240:
|
||||
case 241:
|
||||
case 242:
|
||||
case 243:
|
||||
case 244:
|
||||
case 245:
|
||||
case 252:
|
||||
case 253:
|
||||
vd = 0;
|
||||
break;
|
||||
}
|
||||
if (vd && (Chance(vd) || nNextSprite < 0))
|
||||
{
|
||||
sub_76A08(pSprite2, pSprite, NULL);
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pXSprite->data1 = ClipLow(pXSprite->data1-1, 0);
|
||||
evPost(nSprite, 3, 0, CALLBACK_ID_1);
|
||||
}
|
||||
}
|
||||
|
||||
void(*gCallback[kCallbackMax])(int) =
|
||||
{
|
||||
FlameLick,
|
||||
Remove,
|
||||
FlareBurst,
|
||||
FlareSpark,
|
||||
FlareSparkLite,
|
||||
ZombieSpurt,
|
||||
BloodSpurt,
|
||||
sub_74C20,
|
||||
DynPuff,
|
||||
Respawn,
|
||||
PlayerBubble,
|
||||
EnemyBubble,
|
||||
CounterCheck,
|
||||
FinishHim,
|
||||
sub_76140,
|
||||
sub_74D04,
|
||||
sub_763BC,
|
||||
sub_765B8,
|
||||
sub_768E8,
|
||||
sub_766B8,
|
||||
sub_769B4,
|
||||
sub_76B78
|
||||
};
|
53
source/blood/src/callback.h
Normal file
53
source/blood/src/callback.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
|
||||
enum CALLBACK_ID {
|
||||
CALLBACK_ID_NONE = -1,
|
||||
CALLBACK_ID_0 = 0,
|
||||
CALLBACK_ID_1,
|
||||
CALLBACK_ID_2,
|
||||
CALLBACK_ID_3,
|
||||
CALLBACK_ID_4,
|
||||
CALLBACK_ID_5,
|
||||
CALLBACK_ID_6,
|
||||
CALLBACK_ID_7,
|
||||
CALLBACK_ID_8,
|
||||
CALLBACK_ID_9,
|
||||
CALLBACK_ID_10,
|
||||
CALLBACK_ID_11,
|
||||
CALLBACK_ID_12,
|
||||
CALLBACK_ID_13,
|
||||
CALLBACK_ID_14,
|
||||
CALLBACK_ID_15,
|
||||
CALLBACK_ID_16,
|
||||
CALLBACK_ID_17,
|
||||
CALLBACK_ID_18,
|
||||
CALLBACK_ID_19,
|
||||
CALLBACK_ID_20,
|
||||
CALLBACK_ID_21,
|
||||
kCallbackMax
|
||||
};
|
||||
|
||||
extern void (*gCallback[kCallbackMax])(int);
|
136
source/blood/src/choke.cpp
Normal file
136
source/blood/src/choke.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "build.h"
|
||||
#include "compat.h"
|
||||
#include "common_game.h"
|
||||
#include "blood.h"
|
||||
#include "choke.h"
|
||||
#include "globals.h"
|
||||
#include "levels.h"
|
||||
#include "player.h"
|
||||
#include "qav.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
void CChoke::sub_83F54(char *a1, int _x, int _y, void (*a2)(PLAYER*))
|
||||
{
|
||||
at14 = _x;
|
||||
at18 = _y;
|
||||
at0 = a1;
|
||||
at1c = a2;
|
||||
if (!at4 && at0)
|
||||
{
|
||||
at4 = gSysRes.Lookup(at0, "QAV");
|
||||
if (!at4)
|
||||
ThrowError("Could not load QAV %s\n", at0);
|
||||
at8 = (QAV*)gSysRes.Lock(at4);
|
||||
at8->nSprite = -1;
|
||||
at8->x = at14;
|
||||
at8->y = at18;
|
||||
at8->Preload();
|
||||
sub_84218();
|
||||
}
|
||||
}
|
||||
|
||||
void CChoke::sub_83ff0(int a1, void(*a2)(PLAYER*))
|
||||
{
|
||||
at0 = NULL;
|
||||
at1c = a2;
|
||||
if (!at4 && a1 != -1)
|
||||
{
|
||||
at4 = gSysRes.Lookup(a1, "QAV");
|
||||
if (!at4)
|
||||
ThrowError("Could not load QAV %d\n", a1);
|
||||
at8 = (QAV*)gSysRes.Lock(at4);
|
||||
at8->nSprite = -1;
|
||||
at8->x = at14;
|
||||
at8->y = at18;
|
||||
at8->Preload();
|
||||
sub_84218();
|
||||
}
|
||||
}
|
||||
|
||||
void CChoke::sub_84080(char *a1, void(*a2)(PLAYER*))
|
||||
{
|
||||
at0 = a1;
|
||||
at1c = a2;
|
||||
if (!at4 && at0)
|
||||
{
|
||||
at4 = gSysRes.Lookup(at0, "QAV");
|
||||
if (!at4)
|
||||
ThrowError("Could not load QAV %s\n", at0);
|
||||
at8 = (QAV*)gSysRes.Lock(at4);
|
||||
at8->nSprite = -1;
|
||||
at8->x = at14;
|
||||
at8->y = at18;
|
||||
at8->Preload();
|
||||
sub_84218();
|
||||
}
|
||||
}
|
||||
|
||||
void CChoke::sub_84110(int x, int y)
|
||||
{
|
||||
if (!at4)
|
||||
return;
|
||||
int v4 = gFrameClock;
|
||||
gFrameClock = gGameClock;
|
||||
at8->x = x;
|
||||
at8->y = y;
|
||||
int vd = totalclock-at10;
|
||||
at10 = totalclock;
|
||||
atc -= vd;
|
||||
if (atc <= 0 || atc > at8->at10)
|
||||
atc = at8->at10;
|
||||
int vdi = at8->at10-atc;
|
||||
at8->Play(vdi-vd, vdi, -1, NULL);
|
||||
int vb = windowxy1.x;
|
||||
int v10 = windowxy1.y;
|
||||
int vc = windowxy2.x;
|
||||
int v8 = windowxy2.y;
|
||||
windowxy1.x = windowxy1.y = 0;
|
||||
windowxy2.x = xdim-1;
|
||||
windowxy2.y = ydim-1;
|
||||
at8->Draw(vdi, 10, 0, 0);
|
||||
windowxy1.x = vb;
|
||||
windowxy1.y = v10;
|
||||
windowxy2.x = vc;
|
||||
windowxy2.y = v8;
|
||||
gFrameClock = v4;
|
||||
}
|
||||
|
||||
void CChoke::sub_84218()
|
||||
{
|
||||
atc = at8->at10;
|
||||
at10 = totalclock;
|
||||
}
|
||||
|
||||
void sub_84230(PLAYER *pPlayer)
|
||||
{
|
||||
int t = gGameOptions.nDifficulty+2;
|
||||
if (pPlayer->at372 < 64)
|
||||
pPlayer->at372 = ClipHigh(pPlayer->at372+t, 64);
|
||||
if (pPlayer->at372 > (7-gGameOptions.nDifficulty)*5)
|
||||
pPlayer->at36a = ClipHigh(pPlayer->at36a+t*4, 128);
|
||||
}
|
||||
|
||||
CChoke gChoke;
|
61
source/blood/src/choke.h
Normal file
61
source/blood/src/choke.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "common_game.h"
|
||||
#include "player.h"
|
||||
#include "qav.h"
|
||||
#include "resource.h"
|
||||
|
||||
class CChoke
|
||||
{
|
||||
public:
|
||||
CChoke()
|
||||
{
|
||||
at0 = NULL;
|
||||
at4 = NULL;
|
||||
at8 = NULL;
|
||||
atc = 0;
|
||||
at10 = 0;
|
||||
at1c = NULL;
|
||||
at14 = 0;
|
||||
at18 = 0;
|
||||
};
|
||||
void sub_83F54(char *a1, int _x, int _y, void(*a2)(PLAYER*));
|
||||
void sub_83ff0(int a1, void(*a2)(PLAYER*));
|
||||
void sub_84080(char *a1, void(*a2)(PLAYER*));
|
||||
void sub_84110(int x, int y);
|
||||
void sub_84218();
|
||||
char *at0;
|
||||
DICTNODE *at4;
|
||||
QAV *at8;
|
||||
int atc;
|
||||
int at10;
|
||||
int at14;
|
||||
int at18;
|
||||
void(*at1c)(PLAYER *);
|
||||
};
|
||||
|
||||
void sub_84230(PLAYER*);
|
||||
|
||||
extern CChoke gChoke;
|
748
source/blood/src/common.cpp
Normal file
748
source/blood/src/common.cpp
Normal file
|
@ -0,0 +1,748 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Common non-engine code/data for EDuke32 and Mapster32
|
||||
//
|
||||
|
||||
#include "compat.h"
|
||||
#include "build.h"
|
||||
#include "baselayer.h"
|
||||
#include "palette.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define NEED_SHLWAPI_H
|
||||
# include "windows_inc.h"
|
||||
# include "winbits.h"
|
||||
# ifndef KEY_WOW64_64KEY
|
||||
# define KEY_WOW64_64KEY 0x0100
|
||||
# endif
|
||||
# ifndef KEY_WOW64_32KEY
|
||||
# define KEY_WOW64_32KEY 0x0200
|
||||
# endif
|
||||
#elif defined __APPLE__
|
||||
# include "osxbits.h"
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "common_game.h"
|
||||
|
||||
// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
|
||||
char *g_grpNamePtr = NULL;
|
||||
|
||||
const char *G_DefaultGrpFile(void)
|
||||
{
|
||||
return "nblood.pk3";
|
||||
}
|
||||
|
||||
const char *G_DefaultDefFile(void)
|
||||
{
|
||||
return "blood.def";
|
||||
}
|
||||
|
||||
const char *G_GrpFile(void)
|
||||
{
|
||||
return (g_grpNamePtr == NULL) ? G_DefaultGrpFile() : g_grpNamePtr;
|
||||
}
|
||||
|
||||
const char *G_DefFile(void)
|
||||
{
|
||||
return (g_defNamePtr == NULL) ? G_DefaultDefFile() : g_defNamePtr;
|
||||
}
|
||||
|
||||
static char g_rootDir[BMAX_PATH];
|
||||
|
||||
int g_useCwd;
|
||||
int32_t g_groupFileHandle;
|
||||
|
||||
void G_ExtPreInit(int32_t argc,char const * const * argv)
|
||||
{
|
||||
g_useCwd = G_CheckCmdSwitch(argc, argv, "-usecwd");
|
||||
|
||||
#ifdef _WIN32
|
||||
GetModuleFileName(NULL,g_rootDir,BMAX_PATH);
|
||||
Bcorrectfilename(g_rootDir,1);
|
||||
//chdir(g_rootDir);
|
||||
#else
|
||||
getcwd(g_rootDir,BMAX_PATH);
|
||||
strcat(g_rootDir,"/");
|
||||
#endif
|
||||
}
|
||||
|
||||
void G_ExtInit(void)
|
||||
{
|
||||
char cwd[BMAX_PATH];
|
||||
|
||||
#ifdef EDUKE32_OSX
|
||||
char *appdir = Bgetappdir();
|
||||
addsearchpath(appdir);
|
||||
Bfree(appdir);
|
||||
#endif
|
||||
|
||||
if (getcwd(cwd,BMAX_PATH) && Bstrcmp(cwd,"/") != 0)
|
||||
addsearchpath(cwd);
|
||||
|
||||
if (CommandPaths)
|
||||
{
|
||||
int32_t i;
|
||||
struct strllist *s;
|
||||
while (CommandPaths)
|
||||
{
|
||||
s = CommandPaths->next;
|
||||
i = addsearchpath(CommandPaths->str);
|
||||
if (i < 0)
|
||||
{
|
||||
initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
|
||||
i==-1 ? "not a directory" : "no such directory");
|
||||
}
|
||||
|
||||
Bfree(CommandPaths->str);
|
||||
Bfree(CommandPaths);
|
||||
CommandPaths = s;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!access("user_profiles_enabled", F_OK))
|
||||
#else
|
||||
if (g_useCwd == 0 && access("user_profiles_disabled", F_OK))
|
||||
#endif
|
||||
{
|
||||
char *homedir;
|
||||
int32_t asperr;
|
||||
|
||||
if ((homedir = Bgethomedir()))
|
||||
{
|
||||
Bsnprintf(cwd,sizeof(cwd),"%s/"
|
||||
#if defined(_WIN32)
|
||||
APPNAME
|
||||
#elif defined(GEKKO)
|
||||
"apps/" APPBASENAME
|
||||
#else
|
||||
".config/" APPBASENAME
|
||||
#endif
|
||||
,homedir);
|
||||
asperr = addsearchpath(cwd);
|
||||
if (asperr == -2)
|
||||
{
|
||||
if (Bmkdir(cwd,S_IRWXU) == 0) asperr = addsearchpath(cwd);
|
||||
else asperr = -1;
|
||||
}
|
||||
if (asperr == 0)
|
||||
Bchdir(cwd);
|
||||
Bfree(homedir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t G_TryLoadingGrp(char const * const grpfile)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if ((i = initgroupfile(grpfile)) == -1)
|
||||
initprintf("Warning: could not find main data file \"%s\"!\n", grpfile);
|
||||
else
|
||||
initprintf("Using \"%s\" as main game data file.\n", grpfile);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void G_LoadGroups(int32_t autoload)
|
||||
{
|
||||
if (g_modDir[0] != '/')
|
||||
{
|
||||
char cwd[BMAX_PATH];
|
||||
|
||||
Bstrcat(g_rootDir, g_modDir);
|
||||
addsearchpath(g_rootDir);
|
||||
// addsearchpath(mod_dir);
|
||||
|
||||
char path[BMAX_PATH];
|
||||
|
||||
if (getcwd(cwd, BMAX_PATH))
|
||||
{
|
||||
Bsnprintf(path, sizeof(path), "%s/%s", cwd, g_modDir);
|
||||
if (!Bstrcmp(g_rootDir, path))
|
||||
{
|
||||
if (addsearchpath(path) == -2)
|
||||
if (Bmkdir(path, S_IRWXU) == 0)
|
||||
addsearchpath(path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
const char *grpfile = G_GrpFile();
|
||||
G_TryLoadingGrp(grpfile);
|
||||
|
||||
if (autoload)
|
||||
{
|
||||
G_LoadGroupsInDir("autoload");
|
||||
|
||||
//if (i != -1)
|
||||
// G_DoAutoload(grpfile);
|
||||
}
|
||||
|
||||
if (g_modDir[0] != '/')
|
||||
G_LoadGroupsInDir(g_modDir);
|
||||
|
||||
if (g_defNamePtr == NULL)
|
||||
{
|
||||
const char *tmpptr = getenv("BLOODDEF");
|
||||
if (tmpptr)
|
||||
{
|
||||
clearDefNamePtr();
|
||||
g_defNamePtr = dup_filename(tmpptr);
|
||||
initprintf("Using \"%s\" as definitions file\n", g_defNamePtr);
|
||||
}
|
||||
}
|
||||
|
||||
loaddefinitions_game(G_DefFile(), TRUE);
|
||||
|
||||
struct strllist *s;
|
||||
|
||||
int const bakpathsearchmode = pathsearchmode;
|
||||
pathsearchmode = 1;
|
||||
|
||||
while (CommandGrps)
|
||||
{
|
||||
int32_t j;
|
||||
|
||||
s = CommandGrps->next;
|
||||
|
||||
if ((j = initgroupfile(CommandGrps->str)) == -1)
|
||||
initprintf("Could not find file \"%s\".\n", CommandGrps->str);
|
||||
else
|
||||
{
|
||||
g_groupFileHandle = j;
|
||||
initprintf("Using file \"%s\" as game data.\n", CommandGrps->str);
|
||||
if (autoload)
|
||||
G_DoAutoload(CommandGrps->str);
|
||||
}
|
||||
|
||||
Bfree(CommandGrps->str);
|
||||
Bfree(CommandGrps);
|
||||
CommandGrps = s;
|
||||
}
|
||||
pathsearchmode = bakpathsearchmode;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
static int G_ReadRegistryValue(char const * const SubKey, char const * const Value, char * const Output, DWORD * OutputSize)
|
||||
{
|
||||
// KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
|
||||
REGSAM const wow64keys[] = { KEY_WOW64_32KEY, KEY_WOW64_64KEY };
|
||||
|
||||
for (auto &wow64key : wow64keys)
|
||||
{
|
||||
HKEY hkey;
|
||||
LONG keygood = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | wow64key, &hkey);
|
||||
|
||||
if (keygood != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
LONG retval = SHGetValueA(hkey, SubKey, Value, NULL, Output, OutputSize);
|
||||
|
||||
RegCloseKey(hkey);
|
||||
|
||||
if (retval == ERROR_SUCCESS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef EDUKE32_TOUCH_DEVICES
|
||||
#if defined EDUKE32_OSX || defined __linux__ || defined EDUKE32_BSD
|
||||
static void G_AddSteamPaths(const char *basepath)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(basepath);
|
||||
#if 0
|
||||
char buf[BMAX_PATH];
|
||||
|
||||
// PORT-TODO:
|
||||
// Duke Nukem 3D: Megaton Edition (Steam)
|
||||
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot", basepath);
|
||||
addsearchpath(buf);
|
||||
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/dc", basepath);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/nw", basepath);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/vacation", basepath);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
|
||||
// Duke Nukem 3D (3D Realms Anthology (Steam) / Kill-A-Ton Collection 2015)
|
||||
#if defined EDUKE32_OSX
|
||||
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/Duke Nukem 3D.app/drive_c/Program Files/Duke Nukem 3D", basepath);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// A bare-bones "parser" for Valve's KeyValues VDF format.
|
||||
// There is no guarantee this will function properly with ill-formed files.
|
||||
static void KeyValues_SkipWhitespace(char **vdfbuf, char * const vdfbufend)
|
||||
{
|
||||
while (((*vdfbuf)[0] == ' ' || (*vdfbuf)[0] == '\n' || (*vdfbuf)[0] == '\r' || (*vdfbuf)[0] == '\t' || (*vdfbuf)[0] == '\0') && *vdfbuf < vdfbufend)
|
||||
(*vdfbuf)++;
|
||||
|
||||
// comments
|
||||
if ((*vdfbuf) + 2 < vdfbufend && (*vdfbuf)[0] == '/' && (*vdfbuf)[1] == '/')
|
||||
{
|
||||
while ((*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && *vdfbuf < vdfbufend)
|
||||
(*vdfbuf)++;
|
||||
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
}
|
||||
}
|
||||
static void KeyValues_SkipToEndOfQuotedToken(char **vdfbuf, char * const vdfbufend)
|
||||
{
|
||||
(*vdfbuf)++;
|
||||
while ((*vdfbuf)[0] != '\"' && (*vdfbuf)[-1] != '\\' && *vdfbuf < vdfbufend)
|
||||
(*vdfbuf)++;
|
||||
}
|
||||
static void KeyValues_SkipToEndOfUnquotedToken(char **vdfbuf, char * const vdfbufend)
|
||||
{
|
||||
while ((*vdfbuf)[0] != ' ' && (*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && (*vdfbuf)[0] != '\t' && (*vdfbuf)[0] != '\0' && *vdfbuf < vdfbufend)
|
||||
(*vdfbuf)++;
|
||||
}
|
||||
static void KeyValues_SkipNextWhatever(char **vdfbuf, char * const vdfbufend)
|
||||
{
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
|
||||
if (*vdfbuf == vdfbufend)
|
||||
return;
|
||||
|
||||
if ((*vdfbuf)[0] == '{')
|
||||
{
|
||||
(*vdfbuf)++;
|
||||
do
|
||||
{
|
||||
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||
}
|
||||
while ((*vdfbuf)[0] != '}');
|
||||
(*vdfbuf)++;
|
||||
}
|
||||
else if ((*vdfbuf)[0] == '\"')
|
||||
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
|
||||
else if ((*vdfbuf)[0] != '}')
|
||||
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
|
||||
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
}
|
||||
static char* KeyValues_NormalizeToken(char **vdfbuf, char * const vdfbufend)
|
||||
{
|
||||
char *token = *vdfbuf;
|
||||
|
||||
if ((*vdfbuf)[0] == '\"' && *vdfbuf < vdfbufend)
|
||||
{
|
||||
token++;
|
||||
|
||||
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
|
||||
(*vdfbuf)[0] = '\0';
|
||||
|
||||
// account for escape sequences
|
||||
char *writeseeker = token, *readseeker = token;
|
||||
while (readseeker <= *vdfbuf)
|
||||
{
|
||||
if (readseeker[0] == '\\')
|
||||
readseeker++;
|
||||
|
||||
writeseeker[0] = readseeker[0];
|
||||
|
||||
writeseeker++;
|
||||
readseeker++;
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
|
||||
(*vdfbuf)[0] = '\0';
|
||||
|
||||
return token;
|
||||
}
|
||||
static void KeyValues_FindKey(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||
{
|
||||
char *ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||
if (token != NULL) // pass in NULL to find the next key instead of a specific one
|
||||
while (Bstrcmp(ParentKey, token) != 0 && *vdfbuf < vdfbufend)
|
||||
{
|
||||
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||
ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||
}
|
||||
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
}
|
||||
static int32_t KeyValues_FindParentKey(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||
{
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
|
||||
// end of scope
|
||||
if ((*vdfbuf)[0] == '}')
|
||||
return 0;
|
||||
|
||||
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||
|
||||
// ignore the wrong type
|
||||
while ((*vdfbuf)[0] != '{' && *vdfbuf < vdfbufend)
|
||||
{
|
||||
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||
}
|
||||
|
||||
if (*vdfbuf == vdfbufend)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
static char* KeyValues_FindKeyValue(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||
{
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
|
||||
// end of scope
|
||||
if ((*vdfbuf)[0] == '}')
|
||||
return NULL;
|
||||
|
||||
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||
|
||||
// ignore the wrong type
|
||||
while ((*vdfbuf)[0] == '{' && *vdfbuf < vdfbufend)
|
||||
{
|
||||
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||
}
|
||||
|
||||
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||
|
||||
if (*vdfbuf == vdfbufend)
|
||||
return NULL;
|
||||
|
||||
return KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||
}
|
||||
|
||||
static void G_ParseSteamKeyValuesForPaths(const char *vdf)
|
||||
{
|
||||
int32_t fd = Bopen(vdf, BO_RDONLY);
|
||||
int32_t size = Bfilelength(fd);
|
||||
char *vdfbufstart, *vdfbuf, *vdfbufend;
|
||||
|
||||
if (size <= 0)
|
||||
return;
|
||||
|
||||
vdfbufstart = vdfbuf = (char*)Xmalloc(size);
|
||||
size = (int32_t)Bread(fd, vdfbuf, size);
|
||||
Bclose(fd);
|
||||
vdfbufend = vdfbuf + size;
|
||||
|
||||
if (KeyValues_FindParentKey(&vdfbuf, vdfbufend, "LibraryFolders"))
|
||||
{
|
||||
char *result;
|
||||
vdfbuf++;
|
||||
while ((result = KeyValues_FindKeyValue(&vdfbuf, vdfbufend, NULL)) != NULL)
|
||||
G_AddSteamPaths(result);
|
||||
}
|
||||
|
||||
Bfree(vdfbufstart);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void G_AddSearchPaths(void)
|
||||
{
|
||||
#ifndef EDUKE32_TOUCH_DEVICES
|
||||
#if defined __linux__ || defined EDUKE32_BSD
|
||||
char buf[BMAX_PATH];
|
||||
char *homepath = Bgethomedir();
|
||||
|
||||
Bsnprintf(buf, sizeof(buf), "%s/.steam/steam", homepath);
|
||||
G_AddSteamPaths(buf);
|
||||
|
||||
Bsnprintf(buf, sizeof(buf), "%s/.steam/steam/steamapps/libraryfolders.vdf", homepath);
|
||||
G_ParseSteamKeyValuesForPaths(buf);
|
||||
|
||||
Bfree(homepath);
|
||||
|
||||
addsearchpath("/usr/share/games/nblood");
|
||||
addsearchpath("/usr/local/share/games/nblood");
|
||||
#elif defined EDUKE32_OSX
|
||||
char buf[BMAX_PATH];
|
||||
int32_t i;
|
||||
char *applications[] = { osx_getapplicationsdir(0), osx_getapplicationsdir(1) };
|
||||
char *support[] = { osx_getsupportdir(0), osx_getsupportdir(1) };
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Bsnprintf(buf, sizeof(buf), "%s/Steam", support[i]);
|
||||
G_AddSteamPaths(buf);
|
||||
|
||||
Bsnprintf(buf, sizeof(buf), "%s/Steam/steamapps/libraryfolders.vdf", support[i]);
|
||||
G_ParseSteamKeyValuesForPaths(buf);
|
||||
|
||||
#if 0
|
||||
// Duke Nukem 3D: Atomic Edition (GOG.com)
|
||||
Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D.app/Contents/Resources/Duke Nukem 3D.boxer/C.harddisk", applications[i]);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Bsnprintf(buf, sizeof(buf), "%s/NBlood", support[i]);
|
||||
addsearchpath(buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Bfree(applications[i]);
|
||||
Bfree(support[i]);
|
||||
}
|
||||
#elif defined (_WIN32)
|
||||
char buf[BMAX_PATH] = {0};
|
||||
DWORD bufsize;
|
||||
bool found = false;
|
||||
|
||||
// Blood: One Unit Whole Blood (Steam)
|
||||
bufsize = sizeof(buf);
|
||||
if (!found && G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 299030)", "InstallLocation", buf, &bufsize))
|
||||
{
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
found = true;
|
||||
}
|
||||
|
||||
// Blood: One Unit Whole Blood (GOG.com)
|
||||
bufsize = sizeof(buf);
|
||||
if (!found && G_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGONEUNITONEBLOOD", "PATH", buf, &bufsize))
|
||||
{
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
found = true;
|
||||
}
|
||||
|
||||
// Blood: Fresh Supply (Steam)
|
||||
bufsize = sizeof(buf);
|
||||
if (!found && G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1010750)", "InstallLocation", buf, &bufsize))
|
||||
{
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
strncat(buf, R"(\addons\Cryptic Passage)", 23);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
found = true;
|
||||
}
|
||||
|
||||
// Blood: Fresh Supply (GOG.com)
|
||||
bufsize = sizeof(buf);
|
||||
if (!found && G_ReadRegistryValue(R"(SOFTWARE\Wow6432Node\GOG.com\Games\1374469660)", "path", buf, &bufsize))
|
||||
{
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
strncat(buf, R"(\addons\Cryptic Passage)", 23);
|
||||
addsearchpath_user(buf, SEARCHPATH_REMOVE);
|
||||
found = true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void G_CleanupSearchPaths(void)
|
||||
{
|
||||
removesearchpaths_withuser(SEARCHPATH_REMOVE);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
struct strllist *CommandPaths, *CommandGrps;
|
||||
|
||||
void G_AddGroup(const char *buffer)
|
||||
{
|
||||
char buf[BMAX_PATH];
|
||||
|
||||
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
|
||||
|
||||
Bstrcpy(buf, buffer);
|
||||
|
||||
if (Bstrchr(buf,'.') == 0)
|
||||
Bstrcat(buf,".grp");
|
||||
|
||||
s->str = Xstrdup(buf);
|
||||
|
||||
if (CommandGrps)
|
||||
{
|
||||
struct strllist *t;
|
||||
for (t = CommandGrps; t->next; t=t->next) ;
|
||||
t->next = s;
|
||||
return;
|
||||
}
|
||||
CommandGrps = s;
|
||||
}
|
||||
|
||||
void G_AddPath(const char *buffer)
|
||||
{
|
||||
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
|
||||
s->str = Xstrdup(buffer);
|
||||
|
||||
if (CommandPaths)
|
||||
{
|
||||
struct strllist *t;
|
||||
for (t = CommandPaths; t->next; t=t->next) ;
|
||||
t->next = s;
|
||||
return;
|
||||
}
|
||||
CommandPaths = s;
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
// loads all group (grp, zip, pk3/4) files in the given directory
|
||||
void G_LoadGroupsInDir(const char *dirname)
|
||||
{
|
||||
static const char *extensions[] = { "*.grp", "*.zip", "*.ssi", "*.pk3", "*.pk4" };
|
||||
char buf[BMAX_PATH];
|
||||
fnlist_t fnlist = FNLIST_INITIALIZER;
|
||||
|
||||
for (auto & extension : extensions)
|
||||
{
|
||||
CACHE1D_FIND_REC *rec;
|
||||
|
||||
fnlist_getnames(&fnlist, dirname, extension, -1, 0);
|
||||
|
||||
for (rec=fnlist.findfiles; rec; rec=rec->next)
|
||||
{
|
||||
Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name);
|
||||
initprintf("Using group file \"%s\".\n", buf);
|
||||
initgroupfile(buf);
|
||||
}
|
||||
|
||||
fnlist_clearnames(&fnlist);
|
||||
}
|
||||
}
|
||||
|
||||
void G_DoAutoload(const char *dirname)
|
||||
{
|
||||
char buf[BMAX_PATH];
|
||||
|
||||
Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname);
|
||||
G_LoadGroupsInDir(buf);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
#ifdef FORMAT_UPGRADE_ELIGIBLE
|
||||
|
||||
static int32_t S_TryFormats(char * const testfn, char * const fn_suffix, char const searchfirst)
|
||||
{
|
||||
#ifdef HAVE_FLAC
|
||||
{
|
||||
Bstrcpy(fn_suffix, ".flac");
|
||||
int32_t const fp = kopen4loadfrommod(testfn, searchfirst);
|
||||
if (fp >= 0)
|
||||
return fp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VORBIS
|
||||
{
|
||||
Bstrcpy(fn_suffix, ".ogg");
|
||||
int32_t const fp = kopen4loadfrommod(testfn, searchfirst);
|
||||
if (fp >= 0)
|
||||
return fp;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t S_TryExtensionReplacements(char * const testfn, char const searchfirst, uint8_t const ismusic)
|
||||
{
|
||||
char * extension = Bstrrchr(testfn, '.');
|
||||
char * const fn_end = Bstrchr(testfn, '\0');
|
||||
|
||||
// ex: grabbag.voc --> grabbag_voc.*
|
||||
if (extension != NULL)
|
||||
{
|
||||
*extension = '_';
|
||||
|
||||
int32_t const fp = S_TryFormats(testfn, fn_end, searchfirst);
|
||||
if (fp >= 0)
|
||||
return fp;
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = fn_end;
|
||||
}
|
||||
|
||||
// ex: grabbag.mid --> grabbag.*
|
||||
if (ismusic)
|
||||
{
|
||||
int32_t const fp = S_TryFormats(testfn, extension, searchfirst);
|
||||
if (fp >= 0)
|
||||
return fp;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t S_OpenAudio(const char *fn, char searchfirst, uint8_t const ismusic)
|
||||
{
|
||||
int32_t const origfp = kopen4loadfrommod(fn, searchfirst);
|
||||
char const *const origparent = origfp != -1 ? kfileparent(origfp) : NULL;
|
||||
uint32_t const parentlength = origparent != NULL ? Bstrlen(origparent) : 0;
|
||||
|
||||
auto testfn = (char *)Xmalloc(Bstrlen(fn) + 12 + parentlength); // "music/" + overestimation of parent minus extension + ".flac" + '\0'
|
||||
|
||||
// look in ./
|
||||
// ex: ./grabbag.mid
|
||||
Bstrcpy(testfn, fn);
|
||||
int32_t fp = S_TryExtensionReplacements(testfn, searchfirst, ismusic);
|
||||
if (fp >= 0)
|
||||
goto success;
|
||||
|
||||
// look in ./music/<file's parent GRP name>/
|
||||
// ex: ./music/duke3d/grabbag.mid
|
||||
// ex: ./music/nwinter/grabbag.mid
|
||||
if (origparent != NULL)
|
||||
{
|
||||
char const * const parentextension = Bstrrchr(origparent, '.');
|
||||
uint32_t const namelength = parentextension != NULL ? (unsigned)(parentextension - origparent) : parentlength;
|
||||
|
||||
Bsprintf(testfn, "music/%.*s/%s", namelength, origparent, fn);
|
||||
fp = S_TryExtensionReplacements(testfn, searchfirst, ismusic);
|
||||
if (fp >= 0)
|
||||
goto success;
|
||||
}
|
||||
|
||||
// look in ./music/
|
||||
// ex: ./music/grabbag.mid
|
||||
Bsprintf(testfn, "music/%s", fn);
|
||||
fp = S_TryExtensionReplacements(testfn, searchfirst, ismusic);
|
||||
if (fp >= 0)
|
||||
goto success;
|
||||
|
||||
fp = origfp;
|
||||
success:
|
||||
Bfree(testfn);
|
||||
if (fp != origfp)
|
||||
kclose(origfp);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
499
source/blood/src/common_game.h
Normal file
499
source/blood/src/common_game.h
Normal file
|
@ -0,0 +1,499 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "baselayer.h"
|
||||
#include "build.h"
|
||||
#include "cache1d.h"
|
||||
#include "common.h"
|
||||
#include "pragmas.h"
|
||||
#include "misc.h"
|
||||
#include "network.h"
|
||||
|
||||
extern int g_useCwd;
|
||||
|
||||
#ifndef APPNAME
|
||||
#define APPNAME "NBlood"
|
||||
#endif
|
||||
|
||||
#ifndef APPBASENAME
|
||||
#define APPBASENAME "nblood"
|
||||
#endif
|
||||
|
||||
#define BYTEVERSION 102
|
||||
#define EXEVERSION 101
|
||||
|
||||
void _SetErrorLoc(const char *pzFile, int nLine);
|
||||
void _ThrowError(const char *pzFormat, ...);
|
||||
void __dassert(const char *pzExpr, const char *pzFile, int nLine);
|
||||
|
||||
#define ThrowError(...) \
|
||||
{ \
|
||||
_SetErrorLoc(__FILE__,__LINE__); \
|
||||
_ThrowError(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define dassert(x) if (!(x)) __dassert(#x,__FILE__,__LINE__)
|
||||
|
||||
#define kMaxSectors 1024
|
||||
#define kMaxWalls 8192
|
||||
#define kMaxSprites 4096
|
||||
|
||||
#define kMaxTiles MAXTILES
|
||||
#define kMaxStatus MAXSTATUS
|
||||
#define kMaxPlayers 8
|
||||
#define kMaxViewSprites maxspritesonscreen
|
||||
|
||||
#define kMaxVoxels MAXVOXELS
|
||||
|
||||
#define kTicRate 120
|
||||
#define kTicsPerFrame 4
|
||||
#define kTicsPerSec (kTicRate/kTicsPerFrame)
|
||||
|
||||
// NUKE-TODO:
|
||||
#define OSDTEXT_DEFAULT "^00"
|
||||
#define OSDTEXT_DARKRED "^00"
|
||||
#define OSDTEXT_GREEN "^00"
|
||||
#define OSDTEXT_RED "^00"
|
||||
#define OSDTEXT_YELLOW "^00"
|
||||
|
||||
#define OSDTEXT_BRIGHT "^S0"
|
||||
|
||||
#define OSD_ERROR OSDTEXT_DARKRED OSDTEXT_BRIGHT
|
||||
|
||||
enum BLOOD_GLOBALFLAGS {
|
||||
BLOOD_FORCE_WIDELOADSCREEN = 1<<0,
|
||||
};
|
||||
|
||||
enum searchpathtypes_t {
|
||||
SEARCHPATH_REMOVE = 1<<0,
|
||||
};
|
||||
|
||||
extern char *g_grpNamePtr;
|
||||
|
||||
extern int loaddefinitions_game(const char *fn, int32_t preload);
|
||||
|
||||
extern void G_AddSearchPaths(void);
|
||||
extern void G_CleanupSearchPaths(void);
|
||||
|
||||
extern void G_ExtPreInit(int32_t argc, char const * const * argv);
|
||||
extern void G_ExtInit(void);
|
||||
|
||||
void G_LoadGroupsInDir(const char *dirname);
|
||||
void G_DoAutoload(const char *dirname);
|
||||
extern void G_LoadGroups(int32_t autoload);
|
||||
|
||||
#define G_ModDirSnprintf(buf, size, basename, ...) \
|
||||
(((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/" basename, g_modDir, ##__VA_ARGS__) : Bsnprintf(buf, size, basename, ##__VA_ARGS__)) \
|
||||
>= ((int32_t)size) - 1)
|
||||
|
||||
#define G_ModDirSnprintfLite(buf, size, basename) \
|
||||
((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/%s", g_modDir, basename) : Bsnprintf(buf, size, "%s", basename))
|
||||
|
||||
static inline void G_HandleAsync(void)
|
||||
{
|
||||
handleevents();
|
||||
netGetPackets();
|
||||
}
|
||||
|
||||
#if defined HAVE_FLAC || defined HAVE_VORBIS
|
||||
# define FORMAT_UPGRADE_ELIGIBLE
|
||||
extern int32_t S_OpenAudio(const char *fn, char searchfirst, uint8_t ismusic);
|
||||
#else
|
||||
# define S_OpenAudio(fn, searchfirst, ismusic) kopen4loadfrommod(fn, searchfirst)
|
||||
#endif
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
#if 0
|
||||
struct sectortype
|
||||
{
|
||||
short wallptr, wallnum;
|
||||
int ceilingz, floorz;
|
||||
unsigned short ceilingstat, floorstat;
|
||||
short ceilingpicnum, ceilingheinum;
|
||||
signed char ceilingshade;
|
||||
char ceilingpal, ceilingxpanning, ceilingypanning;
|
||||
short floorpicnum, floorheinum;
|
||||
signed char floorshade;
|
||||
char floorpal, floorxpanning, floorypanning;
|
||||
char visibility, filler;
|
||||
unsigned short lotag;
|
||||
short hitag, extra;
|
||||
};
|
||||
|
||||
struct walltype
|
||||
{
|
||||
int x, y;
|
||||
short point2, nextwall, nextsector;
|
||||
unsigned short cstat;
|
||||
short picnum, overpicnum;
|
||||
signed char shade;
|
||||
char pal, xrepeat, yrepeat, xpanning, ypanning;
|
||||
short lotag, hitag, extra;
|
||||
};
|
||||
|
||||
struct spritetype
|
||||
{
|
||||
int x, y, z;
|
||||
short cstat, picnum;
|
||||
signed char shade;
|
||||
char pal, clipdist, filler;
|
||||
unsigned char xrepeat, yrepeat;
|
||||
signed char xoffset, yoffset;
|
||||
short sectnum, statnum;
|
||||
short ang, owner, index, yvel, zvel;
|
||||
short type, hitag, extra;
|
||||
};
|
||||
|
||||
struct PICANM {
|
||||
unsigned int animframes : 5;
|
||||
unsigned int at0_5 : 1;
|
||||
unsigned int animtype : 2;
|
||||
signed int xoffset : 8;
|
||||
signed int yoffset : 8;
|
||||
unsigned int animspeed : 4;
|
||||
unsigned int at3_4 : 3; // type
|
||||
unsigned int at3_7 : 1; // filler
|
||||
};
|
||||
#endif
|
||||
|
||||
struct LOCATION {
|
||||
int x, y, z;
|
||||
int ang;
|
||||
};
|
||||
|
||||
struct POINT2D {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct POINT3D {
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
struct VECTOR2D {
|
||||
int dx, dy;
|
||||
};
|
||||
|
||||
struct Aim {
|
||||
int dx, dy, dz;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
extern char qsprite_filler[], qsector_filler[];
|
||||
|
||||
inline int ksgnf(float f)
|
||||
{
|
||||
if (f < 0)
|
||||
return -1;
|
||||
if (f > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int IncBy(int a, int b)
|
||||
{
|
||||
a += b;
|
||||
int q = a % b;
|
||||
a -= q;
|
||||
if (q < 0)
|
||||
a -= b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int DecBy(int a, int b)
|
||||
{
|
||||
a--;
|
||||
int q = a % b;
|
||||
a -= q;
|
||||
if (q < 0)
|
||||
a -= b;
|
||||
return a;
|
||||
}
|
||||
|
||||
#if 0
|
||||
inline float IncByF(float a, float b)
|
||||
{
|
||||
a += b;
|
||||
float q = fmod(a, b);
|
||||
a -= q;
|
||||
if (q < 0)
|
||||
a -= b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float DecByF(float a, float b)
|
||||
{
|
||||
//a--;
|
||||
a -= fabs(b)*0.001;
|
||||
float q = fmod(a, b);
|
||||
a -= q;
|
||||
if (q < 0)
|
||||
a -= b;
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int ClipLow(int a, int b)
|
||||
{
|
||||
if (a < b)
|
||||
return b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int ClipHigh(int a, int b)
|
||||
{
|
||||
if (a >= b)
|
||||
return b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int ClipRange(int a, int b, int c)
|
||||
{
|
||||
if (a < b)
|
||||
return b;
|
||||
if (a > c)
|
||||
return c;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float ClipRangeF(float a, float b, float c)
|
||||
{
|
||||
if (a < b)
|
||||
return b;
|
||||
if (a > c)
|
||||
return c;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int interpolate(int a, int b, int c)
|
||||
{
|
||||
return a+mulscale16(b-a,c);
|
||||
}
|
||||
|
||||
inline int interpolateang(int a, int b, int c)
|
||||
{
|
||||
return a+mulscale16(((b-a+1024)&2047)-1024, c);
|
||||
}
|
||||
|
||||
inline fix16_t interpolateangfix16(fix16_t a, fix16_t b, int c)
|
||||
{
|
||||
return a+mulscale16(((b-a+0x4000000)&0x7ffffff)-0x4000000, c);
|
||||
}
|
||||
|
||||
inline char Chance(int a1)
|
||||
{
|
||||
return wrand() < (a1>>1);
|
||||
}
|
||||
|
||||
inline unsigned int Random(int a1)
|
||||
{
|
||||
return mulscale(wrand(), a1, 15);
|
||||
}
|
||||
|
||||
inline int Random2(int a1)
|
||||
{
|
||||
return mulscale(wrand(), a1, 14)-a1;
|
||||
}
|
||||
|
||||
inline int Random3(int a1)
|
||||
{
|
||||
return mulscale(wrand()+wrand(), a1, 15) - a1;
|
||||
}
|
||||
|
||||
inline unsigned int QRandom(int a1)
|
||||
{
|
||||
return mulscale(qrand(), a1, 15);
|
||||
}
|
||||
|
||||
inline int QRandom2(int a1)
|
||||
{
|
||||
return mulscale(qrand(), a1, 14)-a1;
|
||||
}
|
||||
|
||||
inline void SetBitString(char *pArray, int nIndex)
|
||||
{
|
||||
pArray[nIndex>>3] |= 1<<(nIndex&7);
|
||||
}
|
||||
|
||||
inline void ClearBitString(char *pArray, int nIndex)
|
||||
{
|
||||
pArray[nIndex >> 3] &= ~(1 << (nIndex & 7));
|
||||
}
|
||||
|
||||
inline char TestBitString(char *pArray, int nIndex)
|
||||
{
|
||||
return pArray[nIndex>>3] & (1<<(nIndex&7));
|
||||
}
|
||||
|
||||
inline int scale(int a1, int a2, int a3, int a4, int a5)
|
||||
{
|
||||
return a4 + (a5-a4) * (a1-a2) / (a3-a2);
|
||||
}
|
||||
|
||||
inline int mulscale16r(int a, int b)
|
||||
{
|
||||
int64_t acc = 1<<(16-1);
|
||||
acc += ((int64_t)a) * b;
|
||||
return (int)(acc>>16);
|
||||
}
|
||||
|
||||
inline int mulscale30r(int a, int b)
|
||||
{
|
||||
int64_t acc = 1<<(30-1);
|
||||
acc += ((int64_t)a) * b;
|
||||
return (int)(acc>>30);
|
||||
}
|
||||
|
||||
inline int dmulscale30r(int a, int b, int c, int d)
|
||||
{
|
||||
int64_t acc = 1<<(30-1);
|
||||
acc += ((int64_t)a) * b;
|
||||
acc += ((int64_t)c) * d;
|
||||
return (int)(acc>>30);
|
||||
}
|
||||
|
||||
inline int approxDist(int dx, int dy)
|
||||
{
|
||||
dx = klabs(dx);
|
||||
dy = klabs(dy);
|
||||
if (dx > dy)
|
||||
dy = (3*dy)>>3;
|
||||
else
|
||||
dx = (3*dx)>>3;
|
||||
return dx+dy;
|
||||
}
|
||||
|
||||
class Rect {
|
||||
public:
|
||||
int x1, y1, x2, y2;
|
||||
Rect(int _x1, int _y1, int _x2, int _y2)
|
||||
{
|
||||
x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2;
|
||||
}
|
||||
bool isValid(void) const
|
||||
{
|
||||
return x1 < x2 && y1 < y2;
|
||||
}
|
||||
char isEmpty(void) const
|
||||
{
|
||||
return !(x1 < x2 && y1 < y2);
|
||||
}
|
||||
bool operator!(void) const
|
||||
{
|
||||
return isEmpty();
|
||||
}
|
||||
|
||||
Rect & operator&=(Rect &pOther)
|
||||
{
|
||||
x1 = ClipLow(x1, pOther.x1);
|
||||
y1 = ClipLow(y1, pOther.y1);
|
||||
x2 = ClipHigh(x2, pOther.x2);
|
||||
y2 = ClipHigh(y2, pOther.y2);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class BitReader {
|
||||
public:
|
||||
int nBitPos;
|
||||
int nSize;
|
||||
char *pBuffer;
|
||||
BitReader(char *_pBuffer, int _nSize, int _nBitPos) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = _nBitPos; nSize -= nBitPos>>3; }
|
||||
BitReader(char *_pBuffer, int _nSize) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = 0; }
|
||||
int readBit()
|
||||
{
|
||||
if (nSize <= 0)
|
||||
ThrowError("Buffer overflow");
|
||||
int bit = ((*pBuffer)>>nBitPos)&1;
|
||||
if (++nBitPos >= 8)
|
||||
{
|
||||
nBitPos = 0;
|
||||
pBuffer++;
|
||||
nSize--;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
void skipBits(int nBits)
|
||||
{
|
||||
nBitPos += nBits;
|
||||
pBuffer += nBitPos>>3;
|
||||
nSize -= nBitPos>>3;
|
||||
nBitPos &= 7;
|
||||
if ((nSize == 0 && nBitPos > 0) || nSize < 0)
|
||||
ThrowError("Buffer overflow");
|
||||
}
|
||||
unsigned int readUnsigned(int nBits)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
dassert(nBits <= 32);
|
||||
for (int i = 0; i < nBits; i++)
|
||||
n += readBit()<<i;
|
||||
return n;
|
||||
}
|
||||
int readSigned(int nBits)
|
||||
{
|
||||
dassert(nBits <= 32);
|
||||
int n = (int)readUnsigned(nBits);
|
||||
n <<= 32-nBits;
|
||||
n >>= 32-nBits;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
class BitWriter {
|
||||
public:
|
||||
int nBitPos;
|
||||
int nSize;
|
||||
char *pBuffer;
|
||||
BitWriter(char *_pBuffer, int _nSize, int _nBitPos) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = _nBitPos; memset(pBuffer, 0, nSize); nSize -= nBitPos>>3; }
|
||||
BitWriter(char *_pBuffer, int _nSize) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = 0; memset(pBuffer, 0, nSize); }
|
||||
void writeBit(int bit)
|
||||
{
|
||||
if (nSize <= 0)
|
||||
ThrowError("Buffer overflow");
|
||||
*pBuffer |= bit<<nBitPos;
|
||||
if (++nBitPos >= 8)
|
||||
{
|
||||
nBitPos = 0;
|
||||
pBuffer++;
|
||||
nSize--;
|
||||
}
|
||||
}
|
||||
void skipBits(int nBits)
|
||||
{
|
||||
nBitPos += nBits;
|
||||
pBuffer += nBitPos>>3;
|
||||
nSize -= nBitPos>>3;
|
||||
nBitPos &= 7;
|
||||
if ((nSize == 0 && nBitPos > 0) || nSize < 0)
|
||||
ThrowError("Buffer overflow");
|
||||
}
|
||||
void write(int nValue, int nBits)
|
||||
{
|
||||
dassert(nBits <= 32);
|
||||
for (int i = 0; i < nBits; i++)
|
||||
writeBit((nValue>>i)&1);
|
||||
}
|
||||
};
|
||||
|
1079
source/blood/src/config.cpp
Normal file
1079
source/blood/src/config.cpp
Normal file
File diff suppressed because it is too large
Load diff
128
source/blood/src/config.h
Normal file
128
source/blood/src/config.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifndef config_public_h_
|
||||
#define config_public_h_
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "function.h"
|
||||
#include "control.h"
|
||||
#include "_control.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define MAXRIDECULE 10
|
||||
#define MAXRIDECULELENGTH 40
|
||||
#define MAXPLAYERNAME 16
|
||||
|
||||
extern int32_t MouseDeadZone, MouseBias;
|
||||
extern int32_t SmoothInput;
|
||||
extern int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
|
||||
extern int32_t MouseDigitalFunctions[MAXMOUSEAXES][2];
|
||||
extern int32_t MouseAnalogueAxes[MAXMOUSEAXES];
|
||||
extern int32_t MouseAnalogueScale[MAXMOUSEAXES];
|
||||
extern int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2];
|
||||
extern int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
|
||||
extern int32_t JoystickAnalogueAxes[MAXJOYAXES];
|
||||
extern int32_t JoystickAnalogueScale[MAXJOYAXES];
|
||||
extern int32_t JoystickAnalogueDead[MAXJOYAXES];
|
||||
extern int32_t JoystickAnalogueSaturate[MAXJOYAXES];
|
||||
extern uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2];
|
||||
extern int32_t scripthandle;
|
||||
extern int32_t setupread;
|
||||
extern int32_t SoundToggle;
|
||||
extern int32_t MusicToggle;
|
||||
extern int32_t MusicRestartsOnLoadToggle;
|
||||
extern int32_t CDAudioToggle;
|
||||
extern int32_t FXVolume;
|
||||
extern int32_t MusicVolume;
|
||||
extern int32_t CDVolume;
|
||||
extern int32_t NumVoices;
|
||||
extern int32_t NumChannels;
|
||||
extern int32_t NumBits;
|
||||
extern int32_t MixRate;
|
||||
extern int32_t ReverseStereo;
|
||||
extern int32_t MusicDevice;
|
||||
extern int32_t configversion;
|
||||
extern int32_t CheckForUpdates;
|
||||
extern int32_t LastUpdateCheck;
|
||||
extern int32_t useprecache;
|
||||
extern char CommbatMacro[MAXRIDECULE][MAXRIDECULELENGTH];
|
||||
extern char szPlayerName[MAXPLAYERNAME];
|
||||
extern int32_t gTurnSpeed;
|
||||
extern int32_t gDetail;
|
||||
extern int32_t gAutoAim;
|
||||
extern int32_t gWeaponSwitch;
|
||||
extern int32_t gAutoRun;
|
||||
extern int32_t gViewInterpolate;
|
||||
extern int32_t gViewHBobbing;
|
||||
extern int32_t gViewVBobbing;
|
||||
extern int32_t gFollowMap;
|
||||
extern int32_t gOverlayMap;
|
||||
extern int32_t gRotateMap;
|
||||
extern int32_t gAimReticle;
|
||||
extern int32_t gSlopeTilting;
|
||||
extern int32_t gMessageState;
|
||||
extern int32_t gMessageCount;
|
||||
extern int32_t gMessageTime;
|
||||
extern int32_t gMessageFont;
|
||||
extern int32_t gbAdultContent;
|
||||
extern char gzAdultPassword[9];
|
||||
extern int32_t gDoppler;
|
||||
extern int32_t gShowWeapon;
|
||||
extern int32_t gMouseSensitivity;
|
||||
extern int32_t gMouseAiming;
|
||||
extern int32_t gMouseAimingFlipped;
|
||||
extern int32_t gRunKeyMode;
|
||||
extern bool gNoClip;
|
||||
extern bool gInfiniteAmmo;
|
||||
extern bool gFullMap;
|
||||
extern hashtable_t h_gamefuncs;
|
||||
extern int32_t gUpscaleFactor;
|
||||
extern int32_t gBrightness;
|
||||
extern int32_t gLevelStats;
|
||||
extern int32_t gPowerupDuration;
|
||||
extern int32_t gShowMapTitle;
|
||||
extern int32_t MAXCACHE1DSIZE;
|
||||
extern int32_t gFov;
|
||||
extern int32_t gCenterHoriz;
|
||||
extern int32_t gDeliriumBlur;
|
||||
|
||||
int CONFIG_ReadSetup(void);
|
||||
void CONFIG_WriteSetup(uint32_t flags);
|
||||
void CONFIG_SetDefaults(void);
|
||||
void CONFIG_SetupMouse(void);
|
||||
void CONFIG_SetupJoystick(void);
|
||||
void CONFIG_SetDefaultKeys(const char (*keyptr)[MAXGAMEFUNCLEN], bool lazy=false);
|
||||
|
||||
int32_t CONFIG_GetMapBestTime(char const *mapname, uint8_t const *mapmd4);
|
||||
int CONFIG_SetMapBestTime(uint8_t const *mapmd4, int32_t tm);
|
||||
|
||||
int32_t CONFIG_FunctionNameToNum(const char *func);
|
||||
char * CONFIG_FunctionNumToName(int32_t func);
|
||||
|
||||
int32_t CONFIG_AnalogNameToNum(const char *func);
|
||||
const char *CONFIG_AnalogNumToName(int32_t func);
|
||||
|
||||
void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2);
|
||||
|
||||
#endif
|
491
source/blood/src/controls.cpp
Normal file
491
source/blood/src/controls.cpp
Normal file
|
@ -0,0 +1,491 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "compat.h"
|
||||
#include "baselayer.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "joystick.h"
|
||||
#include "control.h"
|
||||
#include "function.h"
|
||||
#include "common_game.h"
|
||||
#include "blood.h"
|
||||
#include "config.h"
|
||||
#include "controls.h"
|
||||
#include "globals.h"
|
||||
#include "levels.h"
|
||||
#include "map2d.h"
|
||||
#include "view.h"
|
||||
|
||||
|
||||
int32_t ctrlCheckAllInput(void)
|
||||
{
|
||||
return (
|
||||
KB_KeyWaiting() ||
|
||||
MOUSE_GetButtons() ||
|
||||
JOYSTICK_GetButtons()
|
||||
);
|
||||
}
|
||||
|
||||
void ctrlClearAllInput(void)
|
||||
{
|
||||
KB_FlushKeyboardQueue();
|
||||
KB_ClearKeysDown();
|
||||
MOUSE_ClearAllButtons();
|
||||
JOYSTICK_ClearAllButtons();
|
||||
}
|
||||
|
||||
GINPUT gInput;
|
||||
bool bSilentAim = false;
|
||||
|
||||
int iTurnCount = 0;
|
||||
|
||||
int32_t GetTime(void)
|
||||
{
|
||||
return gGameClock;
|
||||
}
|
||||
|
||||
void ctrlInit(void)
|
||||
{
|
||||
KB_ClearKeysDown();
|
||||
KB_FlushKeyboardQueue();
|
||||
KB_FlushKeyboardQueueScans();
|
||||
CONTROL_Startup(controltype_keyboardandmouse, &GetTime, 120);
|
||||
CONFIG_SetupMouse();
|
||||
CONFIG_SetupJoystick();
|
||||
|
||||
CONTROL_JoystickEnabled = (gSetup.usejoystick && CONTROL_JoyPresent);
|
||||
CONTROL_MouseEnabled = (gSetup.usemouse && CONTROL_MousePresent);
|
||||
CONTROL_SmoothMouse = SmoothInput;
|
||||
|
||||
// JBF 20040215: evil and nasty place to do this, but joysticks are evil and nasty too
|
||||
for (int i = 0; i < joystick.numAxes; i++)
|
||||
joySetDeadZone(i, JoystickAnalogueDead[i], JoystickAnalogueSaturate[i]);
|
||||
CONTROL_DefineFlag(gamefunc_Move_Forward, false);
|
||||
CONTROL_DefineFlag(gamefunc_Move_Backward, false);
|
||||
CONTROL_DefineFlag(gamefunc_Turn_Left, false);
|
||||
CONTROL_DefineFlag(gamefunc_Turn_Right, false);
|
||||
CONTROL_DefineFlag(gamefunc_Turn_Around, false);
|
||||
CONTROL_DefineFlag(gamefunc_Strafe, false);
|
||||
CONTROL_DefineFlag(gamefunc_Strafe_Left, false);
|
||||
CONTROL_DefineFlag(gamefunc_Strafe_Right, false);
|
||||
CONTROL_DefineFlag(gamefunc_Jump, false);
|
||||
CONTROL_DefineFlag(gamefunc_Crouch, false);
|
||||
CONTROL_DefineFlag(gamefunc_Run, false);
|
||||
CONTROL_DefineFlag(gamefunc_AutoRun, false);
|
||||
CONTROL_DefineFlag(gamefunc_Open, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_Fire, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_Special_Fire, false);
|
||||
CONTROL_DefineFlag(gamefunc_Aim_Up, false);
|
||||
CONTROL_DefineFlag(gamefunc_Aim_Down, false);
|
||||
CONTROL_DefineFlag(gamefunc_Aim_Center, false);
|
||||
CONTROL_DefineFlag(gamefunc_Look_Up, false);
|
||||
CONTROL_DefineFlag(gamefunc_Look_Down, false);
|
||||
CONTROL_DefineFlag(gamefunc_Tilt_Left, false);
|
||||
CONTROL_DefineFlag(gamefunc_Tilt_Right, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_1, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_2, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_3, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_4, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_5, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_6, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_7, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_8, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_9, false);
|
||||
CONTROL_DefineFlag(gamefunc_Weapon_10, false);
|
||||
CONTROL_DefineFlag(gamefunc_Inventory_Use, false);
|
||||
CONTROL_DefineFlag(gamefunc_Inventory_Left, false);
|
||||
CONTROL_DefineFlag(gamefunc_Inventory_Right, false);
|
||||
CONTROL_DefineFlag(gamefunc_Map_Toggle, false);
|
||||
CONTROL_DefineFlag(gamefunc_Map_Follow_Mode, false);
|
||||
CONTROL_DefineFlag(gamefunc_Shrink_Screen, false);
|
||||
CONTROL_DefineFlag(gamefunc_Enlarge_Screen, false);
|
||||
CONTROL_DefineFlag(gamefunc_Send_Message, false);
|
||||
CONTROL_DefineFlag(gamefunc_See_Coop_View, false);
|
||||
CONTROL_DefineFlag(gamefunc_See_Chase_View, false);
|
||||
CONTROL_DefineFlag(gamefunc_Mouse_Aiming, false);
|
||||
CONTROL_DefineFlag(gamefunc_Toggle_Crosshair, false);
|
||||
CONTROL_DefineFlag(gamefunc_Next_Weapon, false);
|
||||
CONTROL_DefineFlag(gamefunc_Previous_Weapon, false);
|
||||
CONTROL_DefineFlag(gamefunc_Holster_Weapon, false);
|
||||
CONTROL_DefineFlag(gamefunc_Show_Opponents_Weapon, false);
|
||||
CONTROL_DefineFlag(gamefunc_BeastVision, false);
|
||||
CONTROL_DefineFlag(gamefunc_CrystalBall, false);
|
||||
CONTROL_DefineFlag(gamefunc_JumpBoots, false);
|
||||
CONTROL_DefineFlag(gamefunc_MedKit, false);
|
||||
CONTROL_DefineFlag(gamefunc_ProximityBombs, false);
|
||||
CONTROL_DefineFlag(gamefunc_RemoteBombs, false);
|
||||
}
|
||||
|
||||
void ctrlTerm(void)
|
||||
{
|
||||
CONTROL_Shutdown();
|
||||
}
|
||||
|
||||
int32_t mouseyaxismode = -1;
|
||||
|
||||
void ctrlGetInput(void)
|
||||
{
|
||||
ControlInfo info;
|
||||
int forward = 0, strafe = 0;
|
||||
fix16_t turn = 0;
|
||||
memset(&gInput, 0, sizeof(gInput));
|
||||
|
||||
if (!gGameStarted || gInputMode != INPUT_MODE_0)
|
||||
{
|
||||
CONTROL_GetInput(&info);
|
||||
return;
|
||||
}
|
||||
|
||||
CONTROL_ProcessBinds();
|
||||
|
||||
if (gMouseAiming)
|
||||
gMouseAim = 0;
|
||||
|
||||
if (BUTTON(gamefunc_Mouse_Aiming))
|
||||
{
|
||||
if (gMouseAiming)
|
||||
gMouseAim = 1;
|
||||
else
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Mouse_Aiming);
|
||||
gMouseAim = !gMouseAim;
|
||||
if (gMouseAim)
|
||||
{
|
||||
if (!bSilentAim)
|
||||
viewSetMessage("Mouse aiming ON");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bSilentAim)
|
||||
viewSetMessage("Mouse aiming OFF");
|
||||
gInput.keyFlags.lookCenter = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gMouseAiming)
|
||||
gInput.keyFlags.lookCenter = 1;
|
||||
|
||||
int32_t const aimMode = (gMouseAim) ? (int32_t)analog_lookingupanddown : MouseAnalogueAxes[1];
|
||||
|
||||
if (aimMode != mouseyaxismode)
|
||||
{
|
||||
CONTROL_MapAnalogAxis(1, aimMode, controldevice_mouse);
|
||||
mouseyaxismode = aimMode;
|
||||
}
|
||||
|
||||
CONTROL_GetInput(&info);
|
||||
|
||||
if (MouseDeadZone)
|
||||
{
|
||||
if (info.dpitch > 0)
|
||||
info.dpitch = max(info.dpitch - MouseDeadZone, 0);
|
||||
else if (info.dpitch < 0)
|
||||
info.dpitch = min(info.dpitch + MouseDeadZone, 0);
|
||||
|
||||
if (info.dyaw > 0)
|
||||
info.dyaw = max(info.dyaw - MouseDeadZone, 0);
|
||||
else if (info.dyaw < 0)
|
||||
info.dyaw = min(info.dyaw + MouseDeadZone, 0);
|
||||
}
|
||||
|
||||
if (MouseBias)
|
||||
{
|
||||
if (klabs(info.dyaw) > klabs(info.dpitch))
|
||||
info.dpitch = tabledivide32_noinline(info.dpitch, MouseBias);
|
||||
else info.dyaw = tabledivide32_noinline(info.dyaw, MouseBias);
|
||||
}
|
||||
|
||||
if (gQuitRequest)
|
||||
gInput.keyFlags.quit = 1;
|
||||
|
||||
if (gGameStarted && gInputMode != INPUT_MODE_2 && gInputMode != INPUT_MODE_1
|
||||
&& BUTTON(gamefunc_Send_Message))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Send_Message);
|
||||
keyFlushScans();
|
||||
gInputMode = INPUT_MODE_2;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_AutoRun))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_AutoRun);
|
||||
gAutoRun = !gAutoRun;
|
||||
if (gAutoRun)
|
||||
viewSetMessage("Auto run ON");
|
||||
else
|
||||
viewSetMessage("Auto run OFF");
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Map_Toggle))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Map_Toggle);
|
||||
viewToggle(gViewMode);
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Map_Follow_Mode))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Map_Follow_Mode);
|
||||
gFollowMap = !gFollowMap;
|
||||
gViewMap.FollowMode(gFollowMap);
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Shrink_Screen))
|
||||
{
|
||||
if (gViewMode == 3)
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Shrink_Screen);
|
||||
viewResizeView(gViewSize + 1);
|
||||
}
|
||||
if (gViewMode == 2 || gViewMode == 4)
|
||||
{
|
||||
gZoom = ClipLow(gZoom - (gZoom >> 4), 64);
|
||||
gViewMap.nZoom = gZoom;
|
||||
}
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Enlarge_Screen))
|
||||
{
|
||||
if (gViewMode == 3)
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Enlarge_Screen);
|
||||
viewResizeView(gViewSize - 1);
|
||||
}
|
||||
if (gViewMode == 2 || gViewMode == 4)
|
||||
{
|
||||
gZoom = ClipHigh(gZoom + (gZoom >> 4), 4096);
|
||||
gViewMap.nZoom = gZoom;
|
||||
}
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Toggle_Crosshair))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Toggle_Crosshair);
|
||||
gAimReticle = !gAimReticle;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Next_Weapon))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Next_Weapon);
|
||||
gInput.keyFlags.nextWeapon = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Previous_Weapon))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Previous_Weapon);
|
||||
gInput.keyFlags.prevWeapon = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Show_Opponents_Weapon))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Show_Opponents_Weapon);
|
||||
gShowWeapon = !gShowWeapon;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Jump))
|
||||
gInput.buttonFlags.jump = 1;
|
||||
|
||||
if (BUTTON(gamefunc_Crouch))
|
||||
gInput.buttonFlags.crouch = 1;
|
||||
|
||||
if (BUTTON(gamefunc_Weapon_Fire))
|
||||
gInput.buttonFlags.shoot = 1;
|
||||
|
||||
if (BUTTON(gamefunc_Weapon_Special_Fire))
|
||||
gInput.buttonFlags.shoot2 = 1;
|
||||
|
||||
if (BUTTON(gamefunc_Open))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Open);
|
||||
gInput.keyFlags.action = 1;
|
||||
}
|
||||
|
||||
gInput.buttonFlags.lookUp = BUTTON(gamefunc_Look_Up);
|
||||
gInput.buttonFlags.lookDown = BUTTON(gamefunc_Look_Down);
|
||||
|
||||
if (gInput.buttonFlags.lookUp || gInput.buttonFlags.lookDown)
|
||||
gInput.keyFlags.lookCenter = 1;
|
||||
else
|
||||
{
|
||||
gInput.buttonFlags.lookUp = BUTTON(gamefunc_Aim_Up);
|
||||
gInput.buttonFlags.lookDown = BUTTON(gamefunc_Aim_Down);
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Aim_Center))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Aim_Center);
|
||||
gInput.keyFlags.lookCenter = 1;
|
||||
}
|
||||
|
||||
gInput.keyFlags.spin180 = BUTTON(gamefunc_Turn_Around);
|
||||
|
||||
if (BUTTON(gamefunc_Inventory_Left))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Inventory_Left);
|
||||
gInput.keyFlags.prevItem = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Inventory_Right))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Inventory_Right);
|
||||
gInput.keyFlags.nextItem = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Inventory_Use))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Inventory_Use);
|
||||
gInput.keyFlags.useItem = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_BeastVision))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_BeastVision);
|
||||
gInput.useFlags.useBeastVision = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_CrystalBall))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_CrystalBall);
|
||||
gInput.useFlags.useCrystalBall = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_JumpBoots))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_JumpBoots);
|
||||
gInput.useFlags.useJumpBoots = 1;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_MedKit))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_MedKit);
|
||||
gInput.useFlags.useMedKit = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (BUTTON(gamefunc_Weapon_1 + i))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Weapon_1 + i);
|
||||
gInput.newWeapon = 1 + i;
|
||||
}
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_ProximityBombs))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_ProximityBombs);
|
||||
gInput.newWeapon = 11;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_RemoteBombs))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_RemoteBombs);
|
||||
gInput.newWeapon = 12;
|
||||
}
|
||||
|
||||
if (BUTTON(gamefunc_Holster_Weapon))
|
||||
{
|
||||
CONTROL_ClearButton(gamefunc_Holster_Weapon);
|
||||
gInput.keyFlags.holsterWeapon = 1;
|
||||
}
|
||||
|
||||
char run = gRunKeyMode ? (BUTTON(gamefunc_Run) | gAutoRun) : (BUTTON(gamefunc_Run) ^ gAutoRun);
|
||||
char run2 = BUTTON(gamefunc_Run);
|
||||
|
||||
gInput.syncFlags.run = run;
|
||||
|
||||
if (BUTTON(gamefunc_Move_Forward))
|
||||
forward += (1+run)<<10;
|
||||
|
||||
if (BUTTON(gamefunc_Move_Backward))
|
||||
forward -= (1+run)<<10;
|
||||
|
||||
char turnLeft = 0, turnRight = 0;
|
||||
|
||||
if (BUTTON(gamefunc_Strafe))
|
||||
{
|
||||
if (BUTTON(gamefunc_Turn_Left))
|
||||
strafe += (1 + run) << 10;
|
||||
if (BUTTON(gamefunc_Turn_Right))
|
||||
strafe -= (1 + run) << 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BUTTON(gamefunc_Strafe_Left))
|
||||
strafe += (1 + run) << 10;
|
||||
if (BUTTON(gamefunc_Strafe_Right))
|
||||
strafe -= (1 + run) << 10;
|
||||
if (BUTTON(gamefunc_Turn_Left))
|
||||
turnLeft = 1;
|
||||
if (BUTTON(gamefunc_Turn_Right))
|
||||
turnRight = 1;
|
||||
}
|
||||
|
||||
if (turnLeft || turnRight)
|
||||
iTurnCount += 4;
|
||||
else
|
||||
iTurnCount = 0;
|
||||
|
||||
if (turnLeft)
|
||||
turn -= fix16_from_int(ClipHigh(12 * iTurnCount, gTurnSpeed))>>2;
|
||||
if (turnRight)
|
||||
turn += fix16_from_int(ClipHigh(12 * iTurnCount, gTurnSpeed))>>2;
|
||||
|
||||
if ((run2 || run) && iTurnCount > 24)
|
||||
turn <<= 1;
|
||||
|
||||
if (BUTTON(gamefunc_Strafe))
|
||||
strafe = ClipRange(strafe - info.dyaw, -2048, 2048);
|
||||
else
|
||||
turn = fix16_clamp(turn + fix16_div(fix16_from_int(info.dyaw), F16(32)), F16(-1024)>>2, F16(1024)>>2);
|
||||
|
||||
strafe = ClipRange(strafe-(info.dx<<5), -2048, 2048);
|
||||
|
||||
#if 0
|
||||
if (info.dz < 0)
|
||||
gInput.mlook = ClipRange((info.dz+127)>>7, -127, 127);
|
||||
else
|
||||
gInput.mlook = ClipRange(info.dz>>7, -127, 127);
|
||||
#endif
|
||||
gInput.q16mlook = fix16_clamp(fix16_div(fix16_from_int(info.dpitch), F16(256)), F16(-127)>>2, F16(127)>>2);
|
||||
if (!gMouseAimingFlipped)
|
||||
gInput.q16mlook = -gInput.q16mlook;
|
||||
forward = ClipRange(forward - info.dz, -2048, 2048);
|
||||
|
||||
if (KB_KeyPressed(sc_Pause)) // 0xc5 in disassembly
|
||||
{
|
||||
gInput.keyFlags.pause = 1;
|
||||
KB_ClearKeyDown(sc_Pause);
|
||||
}
|
||||
|
||||
if (!gViewMap.bFollowMode && gViewMode == 4)
|
||||
{
|
||||
gViewMap.turn = fix16_to_int(turn<<2);
|
||||
gViewMap.forward = forward>>8;
|
||||
gViewMap.strafe = strafe>>8;
|
||||
turn = 0;
|
||||
forward = 0;
|
||||
strafe = 0;
|
||||
}
|
||||
gInput.forward = forward;
|
||||
gInput.q16turn = turn;
|
||||
gInput.strafe = strafe;
|
||||
}
|
112
source/blood/src/controls.h
Normal file
112
source/blood/src/controls.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
union BUTTONFLAGS
|
||||
{
|
||||
int8_t byte;
|
||||
struct
|
||||
{
|
||||
unsigned int jump : 1;
|
||||
unsigned int crouch : 1;
|
||||
unsigned int shoot : 1;
|
||||
unsigned int shoot2 : 1;
|
||||
unsigned int lookUp : 1;
|
||||
unsigned int lookDown : 1;
|
||||
};
|
||||
};
|
||||
|
||||
union KEYFLAGS
|
||||
{
|
||||
int16_t word;
|
||||
struct
|
||||
{
|
||||
unsigned int action : 1;
|
||||
unsigned int jab : 1;
|
||||
unsigned int prevItem : 1;
|
||||
unsigned int nextItem : 1;
|
||||
unsigned int useItem : 1;
|
||||
unsigned int prevWeapon : 1;
|
||||
unsigned int nextWeapon : 1;
|
||||
unsigned int holsterWeapon : 1;
|
||||
unsigned int lookCenter : 1;
|
||||
unsigned int lookLeft : 1;
|
||||
unsigned int lookRight : 1;
|
||||
unsigned int spin180 : 1;
|
||||
unsigned int pause : 1;
|
||||
unsigned int quit : 1;
|
||||
unsigned int restart : 1;
|
||||
};
|
||||
};
|
||||
|
||||
union USEFLAGS
|
||||
{
|
||||
uint8_t byte;
|
||||
struct
|
||||
{
|
||||
unsigned int useBeastVision : 1;
|
||||
unsigned int useCrystalBall : 1;
|
||||
unsigned int useJumpBoots : 1;
|
||||
unsigned int useMedKit : 1;
|
||||
};
|
||||
};
|
||||
|
||||
union SYNCFLAGS
|
||||
{
|
||||
uint8_t byte;
|
||||
struct
|
||||
{
|
||||
unsigned int buttonChange : 1;
|
||||
unsigned int keyChange : 1;
|
||||
unsigned int useChange : 1;
|
||||
unsigned int weaponChange : 1;
|
||||
unsigned int mlookChange : 1;
|
||||
unsigned int run : 1;
|
||||
};
|
||||
};
|
||||
struct GINPUT
|
||||
{
|
||||
SYNCFLAGS syncFlags;
|
||||
int16_t forward;
|
||||
fix16_t q16turn;
|
||||
int16_t strafe;
|
||||
BUTTONFLAGS buttonFlags;
|
||||
KEYFLAGS keyFlags;
|
||||
USEFLAGS useFlags;
|
||||
uint8_t newWeapon;
|
||||
fix16_t q16mlook;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
extern GINPUT gInput;
|
||||
extern bool bSilentAim;
|
||||
extern int32_t gMouseAim; // Should be an int32 due to being passed to OSD
|
||||
|
||||
int32_t ctrlCheckAllInput(void);
|
||||
void ctrlClearAllInput(void);
|
||||
void ctrlInit();
|
||||
void ctrlGetInput();
|
||||
|
284
source/blood/src/credits.cpp
Normal file
284
source/blood/src/credits.cpp
Normal file
|
@ -0,0 +1,284 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include "build.h"
|
||||
#include "compat.h"
|
||||
#include "SmackerDecoder.h"
|
||||
#include "fx_man.h"
|
||||
#include "keyboard.h"
|
||||
#include "common_game.h"
|
||||
#include "blood.h"
|
||||
#include "config.h"
|
||||
#include "controls.h"
|
||||
#include "globals.h"
|
||||
#include "resource.h"
|
||||
#include "screen.h"
|
||||
#include "sound.h"
|
||||
#include "view.h"
|
||||
|
||||
char exitCredits = 0;
|
||||
|
||||
char Wait(int nTicks)
|
||||
{
|
||||
gGameClock = 0;
|
||||
while (gGameClock < nTicks)
|
||||
{
|
||||
timerUpdate();
|
||||
char key = keyGetScan();
|
||||
if (key)
|
||||
{
|
||||
if (key == sc_Escape) // sc_Escape
|
||||
exitCredits = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char DoFade(char r, char g, char b, int nTicks)
|
||||
{
|
||||
dassert(nTicks > 0);
|
||||
scrSetupFade(r, g, b);
|
||||
gGameClock = gFrameClock = 0;
|
||||
do
|
||||
{
|
||||
while (gGameClock < gFrameClock) { timerUpdate();};
|
||||
gFrameClock += 2;
|
||||
scrNextPage();
|
||||
scrFadeAmount(divscale16(ClipHigh(gGameClock, nTicks), nTicks));
|
||||
if (keyGetScan())
|
||||
return 0;
|
||||
} while (gGameClock <= nTicks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char DoUnFade(int nTicks)
|
||||
{
|
||||
dassert(nTicks > 0);
|
||||
scrSetupUnfade();
|
||||
gGameClock = gFrameClock = 0;
|
||||
do
|
||||
{
|
||||
while (gGameClock < gFrameClock) { timerUpdate(); };
|
||||
scrNextPage();
|
||||
scrFadeAmount(0x10000-divscale16(ClipHigh(gGameClock, nTicks), nTicks));
|
||||
if (keyGetScan())
|
||||
return 0;
|
||||
} while (gGameClock <= nTicks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void credLogosDos(void)
|
||||
{
|
||||
char bShift = keystatus[sc_LeftShift] | keystatus[sc_RightShift];
|
||||
videoSetViewableArea(0, 0, xdim-1, ydim-1);
|
||||
DoUnFade(1);
|
||||
videoClearScreen(0);
|
||||
if (bShift)
|
||||
return;
|
||||
{
|
||||
//CSMKPlayer smkPlayer;
|
||||
//if (smkPlayer.PlaySMKWithWAV("LOGO.SMK", 300) == 1)
|
||||
//{
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2050, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
scrNextPage();
|
||||
if (!Wait(360))
|
||||
return;
|
||||
if (!DoFade(0, 0, 0, 60))
|
||||
return;
|
||||
//}
|
||||
//if (smkPlayer.PlaySMKWithWAV("GTI.SMK", 301) == 1)
|
||||
//{
|
||||
videoClearScreen(0);
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2052, 0, 0, 0x0a, 0, 0, xdim-1, ydim-1);
|
||||
scrNextPage();
|
||||
DoUnFade(1);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
if (!Wait(360))
|
||||
return;
|
||||
//}
|
||||
}
|
||||
sndPlaySpecialMusicOrNothing(MUS_INTRO);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
if (!DoFade(0, 0, 0, 60))
|
||||
return;
|
||||
videoClearScreen(0);
|
||||
scrNextPage();
|
||||
if (!DoUnFade(1))
|
||||
return;
|
||||
videoClearScreen(0);
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
||||
scrNextPage();
|
||||
Wait(360);
|
||||
sndFadeSong(4000);
|
||||
}
|
||||
|
||||
void credReset(void)
|
||||
{
|
||||
videoClearScreen(0);
|
||||
scrNextPage();
|
||||
DoFade(0,0,0,1);
|
||||
scrSetupUnfade();
|
||||
DoUnFade(1);
|
||||
}
|
||||
|
||||
int credKOpen4Load(char *&pzFile)
|
||||
{
|
||||
int nLen = strlen(pzFile);
|
||||
for (int i = 0; i < nLen; i++)
|
||||
{
|
||||
if (pzFile[i] == '\\')
|
||||
pzFile[i] = '/';
|
||||
}
|
||||
int nHandle = kopen4loadfrommod(pzFile, 0);
|
||||
if (nHandle == -1)
|
||||
{
|
||||
// Hack
|
||||
if (nLen >= 3 && isalpha(pzFile[0]) && pzFile[1] == ':' && pzFile[2] == '/')
|
||||
{
|
||||
pzFile += 3;
|
||||
nHandle = kopen4loadfrommod(pzFile, 0);
|
||||
}
|
||||
}
|
||||
return nHandle;
|
||||
}
|
||||
|
||||
#define kSMKPal 5
|
||||
#define kSMKTile (MAXTILES-1)
|
||||
|
||||
void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
|
||||
{
|
||||
#if 0
|
||||
CSMKPlayer smkPlayer;
|
||||
if (dword_148E14 >= 0)
|
||||
{
|
||||
if (toupper(*pzSMK) == 'A'+dword_148E14)
|
||||
{
|
||||
if (Redbook.sub_82258() == 0 || Redbook.sub_82258() > 20)
|
||||
return;
|
||||
}
|
||||
Redbook.sub_82554();
|
||||
}
|
||||
smkPlayer.sub_82E6C(pzSMK, pzWAV);
|
||||
#endif
|
||||
if (Bstrlen(_pzSMK) == 0)
|
||||
return;
|
||||
char *pzSMK = Xstrdup(_pzSMK);
|
||||
char *pzWAV = Xstrdup(_pzWAV);
|
||||
char *pzSMK_ = pzSMK;
|
||||
char *pzWAV_ = pzWAV;
|
||||
int nHandleSMK = credKOpen4Load(pzSMK);
|
||||
if (nHandleSMK == -1)
|
||||
{
|
||||
Bfree(pzSMK_);
|
||||
Bfree(pzWAV_);
|
||||
return;
|
||||
}
|
||||
kclose(nHandleSMK);
|
||||
SmackerHandle hSMK = Smacker_Open(pzSMK);
|
||||
if (!hSMK.isValid)
|
||||
{
|
||||
Bfree(pzSMK_);
|
||||
Bfree(pzWAV_);
|
||||
return;
|
||||
}
|
||||
uint32_t nWidth, nHeight;
|
||||
Smacker_GetFrameSize(hSMK, nWidth, nHeight);
|
||||
uint8_t palette[768];
|
||||
uint8_t *pFrame = (uint8_t*)Xmalloc(nWidth*nHeight);
|
||||
waloff[kSMKTile] = (intptr_t)pFrame;
|
||||
tilesiz[kSMKTile].y = nWidth;
|
||||
tilesiz[kSMKTile].x = nHeight;
|
||||
if (!pFrame)
|
||||
{
|
||||
Smacker_Close(hSMK);
|
||||
Bfree(pzSMK_);
|
||||
Bfree(pzWAV_);
|
||||
return;
|
||||
}
|
||||
int nFrameRate = Smacker_GetFrameRate(hSMK);
|
||||
int nFrames = Smacker_GetNumFrames(hSMK);
|
||||
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
paletteSetColorTable(kSMKPal, palette);
|
||||
videoSetPalette(gBrightness>>2, kSMKPal, 8+2);
|
||||
|
||||
int nScale;
|
||||
|
||||
if ((nWidth / (nHeight * 1.2f)) > (1.f * xdim / ydim))
|
||||
nScale = divscale16(320 * xdim * 3, nWidth * ydim * 4);
|
||||
else
|
||||
nScale = divscale16(200, nHeight);
|
||||
|
||||
if (nWav)
|
||||
sndStartWavID(nWav, FXVolume);
|
||||
else
|
||||
{
|
||||
int nHandleWAV = credKOpen4Load(pzWAV);
|
||||
if (nHandleWAV != -1)
|
||||
{
|
||||
kclose(nHandleWAV);
|
||||
sndStartWavDisk(pzWAV, FXVolume);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateDacs(0, true);
|
||||
|
||||
timerUpdate();
|
||||
int32_t nStartTime = totalclock;
|
||||
|
||||
ctrlClearAllInput();
|
||||
|
||||
int nFrame = 0;
|
||||
do
|
||||
{
|
||||
G_HandleAsync();
|
||||
if (scale(totalclock-nStartTime, nFrameRate, kTicRate) < nFrame)
|
||||
continue;
|
||||
|
||||
if (ctrlCheckAllInput())
|
||||
break;
|
||||
|
||||
videoClearScreen(0);
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
paletteSetColorTable(kSMKPal, palette);
|
||||
videoSetPalette(gBrightness >> 2, kSMKPal, 0);
|
||||
tileInvalidate(kSMKTile, 0, 1 << 4); // JBF 20031228
|
||||
Smacker_GetFrame(hSMK, pFrame);
|
||||
rotatesprite_fs(160<<16, 100<<16, nScale, 512, kSMKTile, 0, 0, 2|4|8|64);
|
||||
|
||||
videoNextPage();
|
||||
|
||||
ctrlClearAllInput();
|
||||
nFrame++;
|
||||
Smacker_GetNextFrame(hSMK);
|
||||
} while(nFrame < nFrames);
|
||||
|
||||
Smacker_Close(hSMK);
|
||||
ctrlClearAllInput();
|
||||
FX_StopAllSounds();
|
||||
videoSetPalette(gBrightness >> 2, 0, 8+2);
|
||||
Bfree(pFrame);
|
||||
Bfree(pzSMK_);
|
||||
Bfree(pzWAV_);
|
||||
}
|
27
source/blood/src/credits.h
Normal file
27
source/blood/src/credits.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
void credLogosDos(void);
|
||||
void credReset(void);
|
||||
void credPlaySmk(const char *pzSMK, const char *pzWAV, int nWAV);
|
1240
source/blood/src/db.cpp
Normal file
1240
source/blood/src/db.cpp
Normal file
File diff suppressed because it is too large
Load diff
299
source/blood/src/db.h
Normal file
299
source/blood/src/db.h
Normal file
|
@ -0,0 +1,299 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#define kMaxXSprites 2048
|
||||
#define kMaxXWalls 512
|
||||
#define kMaxXSectors 512
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct AISTATE;
|
||||
|
||||
struct XSPRITE {
|
||||
//int at0;
|
||||
unsigned int atb_2 : 2; // unused //
|
||||
unsigned int atb_6 : 1; // unused // let's use these to add more data
|
||||
unsigned int ate_5 : 2; // unused // fields in the future? must be signed also
|
||||
unsigned int at1a_2 : 6; // unused //
|
||||
|
||||
signed int reference : 14; // at0_0
|
||||
unsigned int state : 1; // State 0
|
||||
unsigned int busy : 17;
|
||||
unsigned int txID : 10; // TX ID
|
||||
unsigned int rxID : 10; // RX ID
|
||||
unsigned int command : 8; // Cmd
|
||||
unsigned int triggerOn : 1; // going ON
|
||||
unsigned int triggerOff : 1; // going OFF
|
||||
unsigned int busyTime : 12; // busyTime
|
||||
unsigned int waitTime : 12; // waitTime
|
||||
unsigned int restState : 1; // restState
|
||||
unsigned int Interrutable : 1; // Interruptable
|
||||
|
||||
unsigned int respawnPending : 2; // respawnPending
|
||||
|
||||
signed int dropMsg : 10; // Drop Item
|
||||
unsigned int Decoupled : 1; // Decoupled
|
||||
unsigned int triggerOnce : 1; // 1-shot
|
||||
unsigned int isTriggered : 1; // works in case if triggerOnce selected
|
||||
|
||||
unsigned int key : 3; // Key
|
||||
unsigned int wave : 2; // Wave
|
||||
unsigned int Push: 1; // Push
|
||||
unsigned int Vector : 1; // Vector
|
||||
unsigned int Impact : 1; // Impact
|
||||
unsigned int Pickup : 1; // Pickup
|
||||
unsigned int Touch : 1; // Touch
|
||||
unsigned int Sight : 1; // Sight
|
||||
unsigned int Proximity : 1; // Proximity
|
||||
unsigned int lSkill : 5; // Launch 12345
|
||||
unsigned int lS : 1; // Single
|
||||
unsigned int lB : 1; // Bloodbath
|
||||
unsigned int lT : 1; // Launch Team
|
||||
unsigned int lC : 1; // Coop
|
||||
unsigned int DudeLockout : 1; // DudeLockout
|
||||
signed int data1 : 16; // Data 1
|
||||
signed int data2 : 16; // Data 2
|
||||
signed int data3 : 16; // Data 3
|
||||
unsigned int data4 : 16; // Data 4
|
||||
unsigned int locked : 1; // Locked
|
||||
unsigned int medium : 2; // medium
|
||||
unsigned int respawn : 2; // Respawn option
|
||||
unsigned int lockMsg : 8; // Lock msg
|
||||
unsigned int health : 20; // 1c_0
|
||||
unsigned int dudeDeaf : 1; // dudeDeaf
|
||||
unsigned int dudeAmbush : 1; // dudeAmbush
|
||||
unsigned int dudeGuard : 1; // dudeGuard
|
||||
unsigned int dudeFlag4 : 1; // DF reserved
|
||||
signed int target : 16; // target sprite
|
||||
signed int targetX : 32; // target x
|
||||
signed int targetY : 32; // target y
|
||||
signed int targetZ : 32; // target z
|
||||
unsigned int goalAng : 11; // Dude goal ang
|
||||
signed int dodgeDir : 2; // Dude dodge direction
|
||||
unsigned int burnTime : 16;
|
||||
signed int burnSource : 16;
|
||||
unsigned int height : 16;
|
||||
unsigned int stateTimer : 16; // ai timer
|
||||
AISTATE *aiState; // ai
|
||||
signed int txIndex : 10; // used by kGDXSequentialTX to keep current TX ID index
|
||||
signed int cumulDamage : 16; // for dudes
|
||||
signed int scale; // used for scaling SEQ size on sprites
|
||||
};
|
||||
|
||||
struct XSECTOR {
|
||||
signed int reference : 14;
|
||||
unsigned int state : 1; // State 0
|
||||
unsigned int busy : 17;
|
||||
unsigned int data : 16; // Data
|
||||
unsigned int txID : 10; // TX ID
|
||||
unsigned int rxID : 10; // RX ID
|
||||
unsigned int at7_2 : 3; // OFF->ON wave
|
||||
unsigned int at7_5 : 3; // ON->OFF wave
|
||||
|
||||
unsigned int command : 8; // Cmd 0
|
||||
unsigned int triggerOn : 1; // Send at ON
|
||||
unsigned int triggerOff : 1; // Send at OFF
|
||||
unsigned int busyTimeA : 12; // OFF->ON busyTime
|
||||
unsigned int waitTimeA : 12; // OFF->ON waitTime
|
||||
unsigned int atd_4 : 1;
|
||||
unsigned int interruptable : 1; // Interruptable
|
||||
|
||||
unsigned int atf_6 : 1; // OFF->ON wait
|
||||
unsigned int atf_7 : 1; // ON->OFF wait
|
||||
signed int amplitude : 8; // Lighting amplitude
|
||||
unsigned int freq : 8; // Lighting freq
|
||||
unsigned int phase : 8; // Lighting phase
|
||||
unsigned int wave : 4; // Lighting wave
|
||||
unsigned int shadeAlways : 1; // Lighting shadeAlways
|
||||
unsigned int shadeFloor : 1; // Lighting floor
|
||||
unsigned int shadeCeiling : 1; // Lighting ceiling
|
||||
unsigned int shadeWalls : 1; // Lighting walls
|
||||
signed int shade : 8; // Lighting value
|
||||
unsigned int panAlways : 1; // Pan always
|
||||
unsigned int panFloor : 1; // Pan floor
|
||||
unsigned int panCeiling : 1; // Pan ceiling
|
||||
unsigned int Drag : 1; // Pan drag
|
||||
unsigned int panVel : 8; // Motion speed
|
||||
unsigned int panAngle : 11; // Motion angle
|
||||
unsigned int Underwater : 1; // Underwater
|
||||
unsigned int Depth : 3; // Depth
|
||||
unsigned int at16_3 : 1;
|
||||
unsigned int decoupled : 1; // Decoupled
|
||||
unsigned int triggerOnce : 1; // 1-shot
|
||||
unsigned int at16_6 : 1;
|
||||
unsigned int Key : 3; // Key
|
||||
unsigned int Push : 1; // Push
|
||||
unsigned int Vector : 1; // Vector
|
||||
unsigned int Reserved : 1; // Reserved
|
||||
unsigned int Enter : 1; // Enter
|
||||
unsigned int Exit : 1; // Exit
|
||||
unsigned int Wallpush : 1; // WallPush
|
||||
unsigned int color : 1; // Color Lights
|
||||
unsigned int at18_1 : 1;
|
||||
unsigned int busyTimeB : 12; // ON->OFF busyTime
|
||||
unsigned int waitTimeB : 12; // ON->OFF waitTime
|
||||
unsigned int at1b_2 : 1;
|
||||
unsigned int at1b_3 : 1;
|
||||
unsigned int ceilpal : 4; // Ceil pal2
|
||||
signed int at1c_0 : 32;
|
||||
signed int at20_0 : 32;
|
||||
signed int at24_0 : 32;
|
||||
signed int at28_0 : 32;
|
||||
unsigned int at2c_0 : 16;
|
||||
unsigned int at2e_0 : 16;
|
||||
unsigned int Crush : 1; // Crush
|
||||
unsigned int at30_1 : 8; // Ceiling x panning frac
|
||||
unsigned int at31_1 : 8; // Ceiling y panning frac
|
||||
unsigned int at32_1 : 8; // Floor x panning frac
|
||||
unsigned int damageType : 3; // DamageType
|
||||
unsigned int floorpal : 4; // Floor pal2
|
||||
unsigned int at34_0 : 8; // Floor y panning frac
|
||||
unsigned int locked : 1; // Locked
|
||||
unsigned int windVel; // Wind vel (by NoOne: changed from 10 bit to use higher velocity values)
|
||||
unsigned int windAng : 11; // Wind ang
|
||||
unsigned int windAlways : 1; // Wind always
|
||||
unsigned int at37_7 : 1;
|
||||
unsigned int bobTheta : 11; // Motion Theta
|
||||
unsigned int bobZRange : 5; // Motion Z range
|
||||
signed int bobSpeed : 12; // Motion speed
|
||||
unsigned int bobAlways : 1; // Motion always
|
||||
unsigned int bobFloor : 1; // Motion bob floor
|
||||
unsigned int bobCeiling : 1; // Motion bob ceiling
|
||||
unsigned int bobRotate : 1; // Motion rotate
|
||||
}; // 60(0x3c) bytes
|
||||
|
||||
struct XWALL {
|
||||
signed int reference : 14;
|
||||
unsigned int state : 1; // State
|
||||
unsigned int busy : 17;
|
||||
signed int data : 16; // Data
|
||||
unsigned int txID : 10; // TX ID
|
||||
unsigned int at7_2 : 6; // unused
|
||||
unsigned int rxID : 10; // RX ID
|
||||
unsigned int command : 8; // Cmd
|
||||
unsigned int triggerOn : 1; // going ON
|
||||
unsigned int triggerOff : 1; // going OFF
|
||||
unsigned int busyTime : 12; // busyTime
|
||||
unsigned int waitTime : 12; // waitTime
|
||||
unsigned int restState : 1; // restState
|
||||
unsigned int interruptable : 1; // Interruptable
|
||||
unsigned int panAlways : 1; // panAlways
|
||||
signed int panXVel : 8; // panX
|
||||
signed int panYVel : 8; // panY
|
||||
unsigned int decoupled : 1; // Decoupled
|
||||
unsigned int triggerOnce : 1; // 1-shot
|
||||
unsigned int isTriggered : 1;
|
||||
unsigned int key : 3; // Key
|
||||
unsigned int triggerPush : 1; // Push
|
||||
unsigned int triggerVector : 1; // Vector
|
||||
unsigned int triggerReserved : 1; // Reserved
|
||||
unsigned int at11_0 : 2; // unused
|
||||
unsigned int xpanFrac : 8; // x panning frac
|
||||
unsigned int ypanFrac : 8; // y panning frac
|
||||
unsigned int locked : 1; // Locked
|
||||
unsigned int dudeLockout : 1; // DudeLockout
|
||||
unsigned int at13_4 : 4; // unused;
|
||||
unsigned int at14_0 : 32; // unused
|
||||
}; // 24(0x18) bytes
|
||||
|
||||
struct MAPSIGNATURE {
|
||||
char signature[4];
|
||||
short version;
|
||||
};
|
||||
|
||||
struct MAPHEADER {
|
||||
int at0; // x
|
||||
int at4; // y
|
||||
int at8; // z
|
||||
short atc; // ang
|
||||
short ate; // sect
|
||||
short at10; // pskybits
|
||||
int at12; // visibility
|
||||
int at16; // song id, Matt
|
||||
char at1a; // parallaxtype
|
||||
int at1b; // map revision
|
||||
short at1f; // numsectors
|
||||
short at21; // numwalls
|
||||
short at23; // numsprites
|
||||
};
|
||||
|
||||
struct MAPHEADER2 {
|
||||
char at0[64];
|
||||
int at40; // xsprite size
|
||||
int at44; // xwall size
|
||||
int at48; // xsector size
|
||||
char pad[52];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
extern unsigned short gStatCount[kMaxStatus + 1];;
|
||||
|
||||
extern bool byte_1A76C6, byte_1A76C7, byte_1A76C8;
|
||||
extern MAPHEADER2 byte_19AE44;
|
||||
|
||||
extern XSPRITE xsprite[kMaxXSprites];
|
||||
extern XSECTOR xsector[kMaxXSectors];
|
||||
extern XWALL xwall[kMaxXWalls];
|
||||
|
||||
extern int xvel[kMaxSprites], yvel[kMaxSprites], zvel[kMaxSprites];
|
||||
|
||||
extern int gVisibility;
|
||||
extern int gMapRev, gSongId, gSkyCount;
|
||||
extern const char *gItemText[];
|
||||
extern const char *gAmmoText[];
|
||||
extern const char *gWeaponText[];
|
||||
|
||||
extern unsigned short nextXSprite[kMaxXSprites];
|
||||
extern unsigned short nextXWall[kMaxXWalls];
|
||||
extern unsigned short nextXSector[kMaxXSectors];
|
||||
|
||||
void InsertSpriteSect(int nSprite, int nSector);
|
||||
void RemoveSpriteSect(int nSprite);
|
||||
void InsertSpriteStat(int nSprite, int nStat);
|
||||
void RemoveSpriteStat(int nSprite);
|
||||
void qinitspritelists(void);
|
||||
int InsertSprite(int nSector, int nStat);
|
||||
int qinsertsprite(short nSector, short nStat);
|
||||
int DeleteSprite(int nSprite);
|
||||
int qdeletesprite(short nSprite);
|
||||
int ChangeSpriteSect(int nSprite, int nSector);
|
||||
int qchangespritesect(short nSprite, short nSector);
|
||||
int ChangeSpriteStat(int nSprite, int nStatus);
|
||||
int qchangespritestat(short nSprite, short nStatus);
|
||||
void InitFreeList(unsigned short *pList, int nCount);
|
||||
void InsertFree(unsigned short *pList, int nIndex);
|
||||
unsigned short dbInsertXSprite(int nSprite);
|
||||
void dbDeleteXSprite(int nXSprite);
|
||||
unsigned short dbInsertXWall(int nWall);
|
||||
void dbDeleteXWall(int nXWall);
|
||||
unsigned short dbInsertXSector(int nSector);
|
||||
void dbDeleteXSector(int nXSector);
|
||||
void dbXSpriteClean(void);
|
||||
void dbXWallClean(void);
|
||||
void dbXSectorClean(void);
|
||||
void dbInit(void);
|
||||
void PropagateMarkerReferences(void);
|
||||
unsigned int dbReadMapCRC(const char *pPath);
|
||||
void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC);
|
625
source/blood/src/demo.cpp
Normal file
625
source/blood/src/demo.cpp
Normal file
|
@ -0,0 +1,625 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "common_game.h"
|
||||
#include "keyboard.h"
|
||||
#include "control.h"
|
||||
#include "osd.h"
|
||||
#include "mmulti.h"
|
||||
|
||||
#include "blood.h"
|
||||
#include "controls.h"
|
||||
#include "demo.h"
|
||||
#include "fire.h"
|
||||
#include "gamemenu.h"
|
||||
#include "globals.h"
|
||||
#include "levels.h"
|
||||
#include "menu.h"
|
||||
#include "messages.h"
|
||||
#include "misc.h"
|
||||
#include "music.h"
|
||||
#include "network.h"
|
||||
#include "player.h"
|
||||
#include "screen.h"
|
||||
#include "view.h"
|
||||
|
||||
int nBuild = 0;
|
||||
|
||||
void ReadGameOptionsLegacy(GAMEOPTIONS &gameOptions, GAMEOPTIONSLEGACY &gameOptionsLegacy)
|
||||
{
|
||||
gameOptions.nGameType = gameOptionsLegacy.nGameType;
|
||||
gameOptions.nDifficulty = gameOptionsLegacy.nDifficulty;
|
||||
gameOptions.nEpisode = gameOptionsLegacy.nEpisode;
|
||||
gameOptions.nLevel = gameOptionsLegacy.nLevel;
|
||||
strcpy(gameOptions.zLevelName, gameOptionsLegacy.zLevelName);
|
||||
strcpy(gameOptions.zLevelSong, gameOptionsLegacy.zLevelSong);
|
||||
gameOptions.nTrackNumber = gameOptionsLegacy.nTrackNumber;
|
||||
strcpy(gameOptions.szSaveGameName, gameOptionsLegacy.szSaveGameName);
|
||||
strcpy(gameOptions.szUserGameName, gameOptionsLegacy.szUserGameName);
|
||||
gameOptions.nSaveGameSlot = gameOptionsLegacy.nSaveGameSlot;
|
||||
gameOptions.picEntry = gameOptionsLegacy.picEntry;
|
||||
gameOptions.uMapCRC = gameOptionsLegacy.uMapCRC;
|
||||
gameOptions.nMonsterSettings = gameOptionsLegacy.nMonsterSettings;
|
||||
gameOptions.uGameFlags = gameOptionsLegacy.uGameFlags;
|
||||
gameOptions.uNetGameFlags = gameOptionsLegacy.uNetGameFlags;
|
||||
gameOptions.nWeaponSettings = gameOptionsLegacy.nWeaponSettings;
|
||||
gameOptions.nItemSettings = gameOptionsLegacy.nItemSettings;
|
||||
gameOptions.nRespawnSettings = gameOptionsLegacy.nRespawnSettings;
|
||||
gameOptions.nTeamSettings = gameOptionsLegacy.nTeamSettings;
|
||||
gameOptions.nMonsterRespawnTime = gameOptionsLegacy.nMonsterRespawnTime;
|
||||
gameOptions.nWeaponRespawnTime = gameOptionsLegacy.nWeaponRespawnTime;
|
||||
gameOptions.nItemRespawnTime = gameOptionsLegacy.nItemRespawnTime;
|
||||
gameOptions.nSpecialRespawnTime = gameOptionsLegacy.nSpecialRespawnTime;
|
||||
}
|
||||
|
||||
CDemo gDemo;
|
||||
|
||||
CDemo::CDemo()
|
||||
{
|
||||
nBuild = 4;
|
||||
at0 = 0;
|
||||
at1 = 0;
|
||||
at3 = 0;
|
||||
hPFile = -1;
|
||||
hRFile = NULL;
|
||||
atb = 0;
|
||||
pFirstDemo = NULL;
|
||||
pCurrentDemo = NULL;
|
||||
at59ef = 0;
|
||||
at2 = 0;
|
||||
memset(&atf, 0, sizeof(atf));
|
||||
m_bLegacy = false;
|
||||
}
|
||||
|
||||
CDemo::~CDemo()
|
||||
{
|
||||
at0 = 0;
|
||||
at1 = 0;
|
||||
at3 = 0;
|
||||
atb = 0;
|
||||
memset(&atf, 0, sizeof(atf));
|
||||
if (hPFile >= 0)
|
||||
{
|
||||
kclose(hPFile);
|
||||
hPFile = -1;
|
||||
}
|
||||
if (hRFile != NULL)
|
||||
{
|
||||
fclose(hRFile);
|
||||
hRFile = NULL;
|
||||
}
|
||||
auto pNextDemo = pFirstDemo;
|
||||
for (auto pDemo = pFirstDemo; pDemo != NULL; pDemo = pNextDemo)
|
||||
{
|
||||
pNextDemo = pDemo->pNext;
|
||||
delete pDemo;
|
||||
}
|
||||
pFirstDemo = NULL;
|
||||
pCurrentDemo = NULL;
|
||||
at59ef = 0;
|
||||
m_bLegacy = false;
|
||||
}
|
||||
|
||||
bool CDemo::Create(const char *pzFile)
|
||||
{
|
||||
char buffer[BMAX_PATH];
|
||||
char vc = 0;
|
||||
if (at0 || at1)
|
||||
ThrowError("CDemo::Create called during demo record/playback process.");
|
||||
if (!pzFile)
|
||||
{
|
||||
for (int i = 0; i < 8 && !vc; i++)
|
||||
{
|
||||
G_ModDirSnprintf(buffer, BMAX_PATH, "%s0%02d.dem", BloodIniPre, i);
|
||||
if (access(buffer, F_OK) != -1)
|
||||
vc = 1;
|
||||
}
|
||||
if (vc == 1)
|
||||
{
|
||||
hRFile = fopen(buffer, "wb");
|
||||
if (hRFile == NULL)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G_ModDirSnprintfLite(buffer, BMAX_PATH, pzFile);
|
||||
hRFile = fopen(buffer, "wb");
|
||||
if (hRFile == NULL)
|
||||
return false;
|
||||
}
|
||||
at0 = 1;
|
||||
atb = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDemo::Write(GINPUT *pPlayerInputs)
|
||||
{
|
||||
dassert(pPlayerInputs != NULL);
|
||||
if (!at0)
|
||||
return;
|
||||
if (atb == 0)
|
||||
{
|
||||
atf.signature = 0x1a4d4445; // '\x1aMDE';
|
||||
atf.nVersion = BYTEVERSION;
|
||||
atf.nBuild = nBuild;
|
||||
atf.nInputCount = 0;
|
||||
atf.nNetPlayers = gNetPlayers;
|
||||
atf.nMyConnectIndex = myconnectindex;
|
||||
atf.nConnectHead = connecthead;
|
||||
memcpy(atf.connectPoints, connectpoint2, sizeof(atf.connectPoints));
|
||||
memcpy(&m_gameOptions, &gGameOptions, sizeof(gGameOptions));
|
||||
fwrite(&atf, sizeof(DEMOHEADER), 1, hRFile);
|
||||
fwrite(&m_gameOptions, sizeof(GAMEOPTIONS), 1, hRFile);
|
||||
}
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
memcpy(&at1aa[atb&1023], &pPlayerInputs[p], sizeof(GINPUT));
|
||||
atb++;
|
||||
if((atb&(kInputBufferSize-1))==0)
|
||||
FlushInput(kInputBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
void CDemo::Close(void)
|
||||
{
|
||||
if (at0)
|
||||
{
|
||||
if (atb&(kInputBufferSize-1))
|
||||
FlushInput(atb&(kInputBufferSize-1));
|
||||
atf.nInputCount = atb;
|
||||
fseek(hRFile, 0, SEEK_SET);
|
||||
fwrite(&atf, sizeof(DEMOHEADER), 1, hRFile);
|
||||
fwrite(&m_gameOptions, sizeof(GAMEOPTIONS), 1, hRFile);
|
||||
}
|
||||
if (hPFile >= 0)
|
||||
{
|
||||
kclose(hPFile);
|
||||
hPFile = -1;
|
||||
}
|
||||
if (hRFile != NULL)
|
||||
{
|
||||
fclose(hRFile);
|
||||
hRFile = NULL;
|
||||
}
|
||||
at0 = 0;
|
||||
at1 = 0;
|
||||
}
|
||||
|
||||
bool CDemo::SetupPlayback(const char *pzFile)
|
||||
{
|
||||
at0 = 0;
|
||||
at1 = 0;
|
||||
if (pzFile)
|
||||
{
|
||||
hPFile = kopen4loadfrommod(pzFile, 0);
|
||||
if (hPFile == -1)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pCurrentDemo)
|
||||
return false;
|
||||
hPFile = kopen4loadfrommod(pCurrentDemo->zName, 0);
|
||||
if (hPFile == -1)
|
||||
return false;
|
||||
}
|
||||
kread(hPFile, &atf, sizeof(DEMOHEADER));
|
||||
#if B_BIG_ENDIAN == 1
|
||||
atf.signature = B_LITTLE32(atf.signature);
|
||||
atf.nVersion = B_LITTLE16(atf.nVersion);
|
||||
atf.nBuild = B_LITTLE32(atf.nBuild);
|
||||
atf.nInputCount = B_LITTLE32(atf.nInputCount);
|
||||
atf.nNetPlayers = B_LITTLE32(atf.nNetPlayers);
|
||||
atf.nMyConnectIndex = B_LITTLE16(atf.nMyConnectIndex);
|
||||
atf.nConnectHead = B_LITTLE16(atf.nConnectHead);
|
||||
atf.nMyConnectIndex = B_LITTLE16(atf.nMyConnectIndex);
|
||||
for (int i = 0; i < 8; i++)
|
||||
atf.connectPoints[i] = B_LITTLE16(atf.connectPoints[i]);
|
||||
#endif
|
||||
// if (aimHeight.signature != '\x1aMED' && aimHeight.signature != '\x1aMDE')
|
||||
if (atf.signature != 0x1a4d4544 && atf.signature != 0x1a4d4445)
|
||||
return 0;
|
||||
m_bLegacy = atf.signature == 0x1a4d4544;
|
||||
if (m_bLegacy)
|
||||
{
|
||||
GAMEOPTIONSLEGACY gameOptions;
|
||||
if (BloodVersion != atf.nVersion)
|
||||
return 0;
|
||||
kread(hPFile, &gameOptions, sizeof(GAMEOPTIONSLEGACY));
|
||||
ReadGameOptionsLegacy(m_gameOptions, gameOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BYTEVERSION != atf.nVersion)
|
||||
return 0;
|
||||
kread(hPFile, &m_gameOptions, sizeof(GAMEOPTIONS));
|
||||
}
|
||||
#if B_BIG_ENDIAN == 1
|
||||
m_gameOptions.nEpisode = B_LITTLE32(m_gameOptions.nEpisode);
|
||||
m_gameOptions.nLevel = B_LITTLE32(m_gameOptions.nLevel);
|
||||
m_gameOptions.nTrackNumber = B_LITTLE32(m_gameOptions.nTrackNumber);
|
||||
m_gameOptions.nSaveGameSlot = B_LITTLE16(m_gameOptions.nSaveGameSlot);
|
||||
m_gameOptions.picEntry = B_LITTLE32(m_gameOptions.picEntry);
|
||||
m_gameOptions.uMapCRC = B_LITTLE32(m_gameOptions.uMapCRC);
|
||||
m_gameOptions.uGameFlags = B_LITTLE32(m_gameOptions.uGameFlags);
|
||||
m_gameOptions.uNetGameFlags = B_LITTLE32(m_gameOptions.uNetGameFlags);
|
||||
m_gameOptions.nMonsterRespawnTime = B_LITTLE32(m_gameOptions.nMonsterRespawnTime);
|
||||
m_gameOptions.nWeaponRespawnTime = B_LITTLE32(m_gameOptions.nWeaponRespawnTime);
|
||||
m_gameOptions.nItemRespawnTime = B_LITTLE32(m_gameOptions.nItemRespawnTime);
|
||||
m_gameOptions.nSpecialRespawnTime = B_LITTLE32(m_gameOptions.nSpecialRespawnTime);
|
||||
#endif
|
||||
at0 = 0;
|
||||
at1 = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CDemo::ProcessKeys(void)
|
||||
{
|
||||
switch (gInputMode)
|
||||
{
|
||||
case INPUT_MODE_1:
|
||||
gGameMenuMgr.Process();
|
||||
break;
|
||||
case INPUT_MODE_2:
|
||||
gPlayerMsg.ProcessKeys();
|
||||
break;
|
||||
case INPUT_MODE_0:
|
||||
{
|
||||
char nKey;
|
||||
while ((nKey = keyGetScan()) != 0)
|
||||
{
|
||||
char UNUSED(alt) = keystatus[0x38] | keystatus[0xb8];
|
||||
char UNUSED(ctrl) = keystatus[0x1d] | keystatus[0x9d];
|
||||
switch (nKey)
|
||||
{
|
||||
case 1:
|
||||
if (!CGameMenuMgr::m_bActive)
|
||||
{
|
||||
gGameMenuMgr.Push(&menuMain, -1);
|
||||
at2 = 1;
|
||||
}
|
||||
break;
|
||||
case 0x58:
|
||||
gViewIndex = connectpoint2[gViewIndex];
|
||||
if (gViewIndex == -1)
|
||||
gViewIndex = connecthead;
|
||||
gView = &gPlayer[gViewIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gInputMode = INPUT_MODE_0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDemo::Playback(void)
|
||||
{
|
||||
CONTROL_BindsEnabled = false;
|
||||
ready2send = 0;
|
||||
int v4 = 0;
|
||||
if (!CGameMenuMgr::m_bActive)
|
||||
{
|
||||
gGameMenuMgr.Push(&menuMain, -1);
|
||||
at2 = 1;
|
||||
}
|
||||
gNetFifoClock = gGameClock;
|
||||
gViewMode = 3;
|
||||
_DEMOPLAYBACK:
|
||||
while (at1 && !gQuitGame)
|
||||
{
|
||||
if (handleevents() && quitevent)
|
||||
{
|
||||
KB_KeyDown[sc_Escape] = 1;
|
||||
quitevent = 0;
|
||||
}
|
||||
MUSIC_Update();
|
||||
while (gGameClock >= gNetFifoClock && !gQuitGame)
|
||||
{
|
||||
if (!v4)
|
||||
{
|
||||
viewResizeView(gViewSize);
|
||||
viewSetMessage("");
|
||||
gNetPlayers = atf.nNetPlayers;
|
||||
atb = atf.nInputCount;
|
||||
myconnectindex = atf.nMyConnectIndex;
|
||||
connecthead = atf.nConnectHead;
|
||||
for (int i = 0; i < 8; i++)
|
||||
connectpoint2[i] = atf.connectPoints[i];
|
||||
memset(gNetFifoHead, 0, sizeof(gNetFifoHead));
|
||||
gNetFifoTail = 0;
|
||||
//memcpy(connectpoint2, aimHeight.connectPoints, sizeof(aimHeight.connectPoints));
|
||||
memcpy(&gGameOptions, &m_gameOptions, sizeof(GAMEOPTIONS));
|
||||
gSkill = gGameOptions.nDifficulty;
|
||||
for (int i = 0; i < 8; i++)
|
||||
playerInit(i, 0);
|
||||
StartLevel(&gGameOptions);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
gProfile[i].nAutoAim = 1;
|
||||
gProfile[i].nWeaponSwitch = 1;
|
||||
}
|
||||
}
|
||||
ready2send = 0;
|
||||
OSD_DispatchQueued();
|
||||
if (!gDemo.at1)
|
||||
break;
|
||||
ProcessKeys();
|
||||
for (int p = connecthead; p >= 0; p = connectpoint2[p])
|
||||
{
|
||||
if ((v4&1023) == 0)
|
||||
{
|
||||
unsigned int nSize = atb-v4;
|
||||
if (nSize > kInputBufferSize)
|
||||
nSize = kInputBufferSize;
|
||||
ReadInput(nSize);
|
||||
}
|
||||
memcpy(&gFifoInput[gNetFifoHead[p]&255], &at1aa[v4&1023], sizeof(GINPUT));
|
||||
gNetFifoHead[p]++;
|
||||
v4++;
|
||||
if (v4 >= atf.nInputCount)
|
||||
{
|
||||
ready2send = 0;
|
||||
if (at59ef != 1)
|
||||
{
|
||||
v4 = 0;
|
||||
Close();
|
||||
NextDemo();
|
||||
gNetFifoClock = gGameClock;
|
||||
goto _DEMOPLAYBACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
int const nOffset = sizeof(DEMOHEADER)+(m_bLegacy ? sizeof(GAMEOPTIONSLEGACY) : sizeof(GAMEOPTIONS));
|
||||
klseek(hPFile, nOffset, SEEK_SET);
|
||||
v4 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
gNetFifoClock += 4;
|
||||
if (!gQuitGame)
|
||||
ProcessFrame();
|
||||
ready2send = 0;
|
||||
}
|
||||
if (viewFPSLimit())
|
||||
{
|
||||
viewDrawScreen();
|
||||
if (gInputMode == INPUT_MODE_1 && CGameMenuMgr::m_bActive)
|
||||
gGameMenuMgr.Draw();
|
||||
}
|
||||
if (TestBitString(gotpic, 2342))
|
||||
{
|
||||
FireProcess();
|
||||
ClearBitString(gotpic, 2342);
|
||||
}
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
void CDemo::StopPlayback(void)
|
||||
{
|
||||
at1 = 0;
|
||||
}
|
||||
|
||||
void CDemo::LoadDemoInfo(void)
|
||||
{
|
||||
auto pDemo = &pFirstDemo;
|
||||
const int opsm = pathsearchmode;
|
||||
at59ef = 0;
|
||||
pathsearchmode = 0;
|
||||
char zFN[BMAX_PATH];
|
||||
Bsnprintf(zFN, BMAX_PATH, "%s*.dem", BloodIniPre);
|
||||
auto pList = klistpath("/", zFN, CACHE1D_FIND_FILE);
|
||||
auto pIterator = pList;
|
||||
while (pIterator != NULL)
|
||||
{
|
||||
int hFile = kopen4loadfrommod(pIterator->name, 0);
|
||||
if (hFile == -1)
|
||||
ThrowError("Error loading demo file header.");
|
||||
kread(hFile, &atf, sizeof(atf));
|
||||
kclose(hFile);
|
||||
#if B_BIG_ENDIAN == 1
|
||||
atf.signature = B_LITTLE32(atf.signature);
|
||||
atf.nVersion = B_LITTLE16(atf.nVersion);
|
||||
#endif
|
||||
if ((atf.signature == 0x1a4d4544 /* '\x1aMED' */&& atf.nVersion == BloodVersion)
|
||||
|| (atf.signature == 0x1a4d4445 /* '\x1aMDE' */ && atf.nVersion == BYTEVERSION))
|
||||
{
|
||||
*pDemo = new DEMOCHAIN;
|
||||
(*pDemo)->pNext = NULL;
|
||||
Bstrncpy((*pDemo)->zName, pIterator->name, BMAX_PATH);
|
||||
at59ef++;
|
||||
pDemo = &(*pDemo)->pNext;
|
||||
}
|
||||
pIterator = pIterator->next;
|
||||
}
|
||||
klistfree(pList);
|
||||
pathsearchmode = opsm;
|
||||
pCurrentDemo = pFirstDemo;
|
||||
}
|
||||
|
||||
void CDemo::NextDemo(void)
|
||||
{
|
||||
pCurrentDemo = pCurrentDemo->pNext ? pCurrentDemo->pNext : pFirstDemo;
|
||||
SetupPlayback(NULL);
|
||||
}
|
||||
|
||||
const int nInputSize = 17;
|
||||
const int nInputSizeLegacy = 22;
|
||||
|
||||
void CDemo::FlushInput(int nCount)
|
||||
{
|
||||
char pBuffer[nInputSize*kInputBufferSize];
|
||||
BitWriter bitWriter(pBuffer, sizeof(pBuffer));
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
GINPUT *pInput = &at1aa[i];
|
||||
bitWriter.writeBit(pInput->syncFlags.buttonChange);
|
||||
bitWriter.writeBit(pInput->syncFlags.keyChange);
|
||||
bitWriter.writeBit(pInput->syncFlags.useChange);
|
||||
bitWriter.writeBit(pInput->syncFlags.weaponChange);
|
||||
bitWriter.writeBit(pInput->syncFlags.mlookChange);
|
||||
bitWriter.writeBit(pInput->syncFlags.run);
|
||||
bitWriter.write(pInput->forward, 16);
|
||||
bitWriter.write(pInput->q16turn, 32);
|
||||
bitWriter.write(pInput->strafe, 16);
|
||||
bitWriter.writeBit(pInput->buttonFlags.jump);
|
||||
bitWriter.writeBit(pInput->buttonFlags.crouch);
|
||||
bitWriter.writeBit(pInput->buttonFlags.shoot);
|
||||
bitWriter.writeBit(pInput->buttonFlags.shoot2);
|
||||
bitWriter.writeBit(pInput->buttonFlags.lookUp);
|
||||
bitWriter.writeBit(pInput->buttonFlags.lookDown);
|
||||
bitWriter.writeBit(pInput->keyFlags.action);
|
||||
bitWriter.writeBit(pInput->keyFlags.jab);
|
||||
bitWriter.writeBit(pInput->keyFlags.prevItem);
|
||||
bitWriter.writeBit(pInput->keyFlags.nextItem);
|
||||
bitWriter.writeBit(pInput->keyFlags.useItem);
|
||||
bitWriter.writeBit(pInput->keyFlags.prevWeapon);
|
||||
bitWriter.writeBit(pInput->keyFlags.nextWeapon);
|
||||
bitWriter.writeBit(pInput->keyFlags.holsterWeapon);
|
||||
bitWriter.writeBit(pInput->keyFlags.lookCenter);
|
||||
bitWriter.writeBit(pInput->keyFlags.lookLeft);
|
||||
bitWriter.writeBit(pInput->keyFlags.lookRight);
|
||||
bitWriter.writeBit(pInput->keyFlags.spin180);
|
||||
bitWriter.writeBit(pInput->keyFlags.pause);
|
||||
bitWriter.writeBit(pInput->keyFlags.quit);
|
||||
bitWriter.writeBit(pInput->keyFlags.restart);
|
||||
bitWriter.writeBit(pInput->useFlags.useBeastVision);
|
||||
bitWriter.writeBit(pInput->useFlags.useCrystalBall);
|
||||
bitWriter.writeBit(pInput->useFlags.useJumpBoots);
|
||||
bitWriter.writeBit(pInput->useFlags.useMedKit);
|
||||
bitWriter.write(pInput->newWeapon, 8);
|
||||
bitWriter.write(pInput->q16mlook, 32);
|
||||
bitWriter.skipBits(1);
|
||||
}
|
||||
fwrite(pBuffer, 1, nInputSize*nCount, hRFile);
|
||||
}
|
||||
|
||||
void CDemo::ReadInput(int nCount)
|
||||
{
|
||||
if (m_bLegacy)
|
||||
{
|
||||
char pBuffer[nInputSizeLegacy*kInputBufferSize];
|
||||
kread(hPFile, pBuffer, nInputSizeLegacy*nCount);
|
||||
BitReader bitReader(pBuffer, sizeof(pBuffer));
|
||||
memset(at1aa, 0, nCount * sizeof(GINPUT));
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
GINPUT *pInput = &at1aa[i];
|
||||
pInput->syncFlags.buttonChange = bitReader.readBit();
|
||||
pInput->syncFlags.keyChange = bitReader.readBit();
|
||||
pInput->syncFlags.useChange = bitReader.readBit();
|
||||
pInput->syncFlags.weaponChange = bitReader.readBit();
|
||||
pInput->syncFlags.mlookChange = bitReader.readBit();
|
||||
pInput->syncFlags.run = bitReader.readBit();
|
||||
bitReader.skipBits(26);
|
||||
pInput->forward = bitReader.readSigned(8) << 8;
|
||||
pInput->q16turn = fix16_from_int(bitReader.readSigned(16) >> 2);
|
||||
pInput->strafe = bitReader.readSigned(8) << 8;
|
||||
pInput->buttonFlags.jump = bitReader.readBit();
|
||||
pInput->buttonFlags.crouch = bitReader.readBit();
|
||||
pInput->buttonFlags.shoot = bitReader.readBit();
|
||||
pInput->buttonFlags.shoot2 = bitReader.readBit();
|
||||
pInput->buttonFlags.lookUp = bitReader.readBit();
|
||||
pInput->buttonFlags.lookDown = bitReader.readBit();
|
||||
bitReader.skipBits(26);
|
||||
pInput->keyFlags.action = bitReader.readBit();
|
||||
pInput->keyFlags.jab = bitReader.readBit();
|
||||
pInput->keyFlags.prevItem = bitReader.readBit();
|
||||
pInput->keyFlags.nextItem = bitReader.readBit();
|
||||
pInput->keyFlags.useItem = bitReader.readBit();
|
||||
pInput->keyFlags.prevWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.nextWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.holsterWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.lookCenter = bitReader.readBit();
|
||||
pInput->keyFlags.lookLeft = bitReader.readBit();
|
||||
pInput->keyFlags.lookRight = bitReader.readBit();
|
||||
pInput->keyFlags.spin180 = bitReader.readBit();
|
||||
pInput->keyFlags.pause = bitReader.readBit();
|
||||
pInput->keyFlags.quit = bitReader.readBit();
|
||||
pInput->keyFlags.restart = bitReader.readBit();
|
||||
bitReader.skipBits(17);
|
||||
pInput->useFlags.useBeastVision = bitReader.readBit();
|
||||
pInput->useFlags.useCrystalBall = bitReader.readBit();
|
||||
pInput->useFlags.useJumpBoots = bitReader.readBit();
|
||||
pInput->useFlags.useMedKit = bitReader.readBit();
|
||||
bitReader.skipBits(28);
|
||||
pInput->newWeapon = bitReader.readUnsigned(8);
|
||||
int mlook = bitReader.readSigned(8);
|
||||
pInput->q16mlook = fix16_from_int(mlook / 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char pBuffer[nInputSize*kInputBufferSize];
|
||||
kread(hPFile, pBuffer, nInputSize*nCount);
|
||||
BitReader bitReader(pBuffer, sizeof(pBuffer));
|
||||
memset(at1aa, 0, nCount * sizeof(GINPUT));
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
GINPUT *pInput = &at1aa[i];
|
||||
pInput->syncFlags.buttonChange = bitReader.readBit();
|
||||
pInput->syncFlags.keyChange = bitReader.readBit();
|
||||
pInput->syncFlags.useChange = bitReader.readBit();
|
||||
pInput->syncFlags.weaponChange = bitReader.readBit();
|
||||
pInput->syncFlags.mlookChange = bitReader.readBit();
|
||||
pInput->syncFlags.run = bitReader.readBit();
|
||||
pInput->forward = bitReader.readSigned(16);
|
||||
pInput->q16turn = bitReader.readSigned(32);
|
||||
pInput->strafe = bitReader.readSigned(16);
|
||||
pInput->buttonFlags.jump = bitReader.readBit();
|
||||
pInput->buttonFlags.crouch = bitReader.readBit();
|
||||
pInput->buttonFlags.shoot = bitReader.readBit();
|
||||
pInput->buttonFlags.shoot2 = bitReader.readBit();
|
||||
pInput->buttonFlags.lookUp = bitReader.readBit();
|
||||
pInput->buttonFlags.lookDown = bitReader.readBit();
|
||||
pInput->keyFlags.action = bitReader.readBit();
|
||||
pInput->keyFlags.jab = bitReader.readBit();
|
||||
pInput->keyFlags.prevItem = bitReader.readBit();
|
||||
pInput->keyFlags.nextItem = bitReader.readBit();
|
||||
pInput->keyFlags.useItem = bitReader.readBit();
|
||||
pInput->keyFlags.prevWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.nextWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.holsterWeapon = bitReader.readBit();
|
||||
pInput->keyFlags.lookCenter = bitReader.readBit();
|
||||
pInput->keyFlags.lookLeft = bitReader.readBit();
|
||||
pInput->keyFlags.lookRight = bitReader.readBit();
|
||||
pInput->keyFlags.spin180 = bitReader.readBit();
|
||||
pInput->keyFlags.pause = bitReader.readBit();
|
||||
pInput->keyFlags.quit = bitReader.readBit();
|
||||
pInput->keyFlags.restart = bitReader.readBit();
|
||||
pInput->useFlags.useBeastVision = bitReader.readBit();
|
||||
pInput->useFlags.useCrystalBall = bitReader.readBit();
|
||||
pInput->useFlags.useJumpBoots = bitReader.readBit();
|
||||
pInput->useFlags.useMedKit = bitReader.readBit();
|
||||
pInput->newWeapon = bitReader.readUnsigned(8);
|
||||
pInput->q16mlook = bitReader.readSigned(32);
|
||||
bitReader.skipBits(1);
|
||||
}
|
||||
}
|
||||
}
|
110
source/blood/src/demo.h
Normal file
110
source/blood/src/demo.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "controls.h"
|
||||
#include "levels.h"
|
||||
|
||||
#define kInputBufferSize 1024
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct GAMEOPTIONSLEGACY {
|
||||
char nGameType;
|
||||
char nDifficulty;
|
||||
int nEpisode;
|
||||
int nLevel;
|
||||
char zLevelName[144];
|
||||
char zLevelSong[144];
|
||||
int nTrackNumber; //at12a;
|
||||
char szSaveGameName[16];
|
||||
char szUserGameName[16];
|
||||
short nSaveGameSlot;
|
||||
int picEntry;
|
||||
unsigned int uMapCRC;
|
||||
char nMonsterSettings;
|
||||
int uGameFlags;
|
||||
int uNetGameFlags;
|
||||
char nWeaponSettings;
|
||||
char nItemSettings;
|
||||
char nRespawnSettings;
|
||||
char nTeamSettings;
|
||||
int nMonsterRespawnTime;
|
||||
int nWeaponRespawnTime;
|
||||
int nItemRespawnTime;
|
||||
int nSpecialRespawnTime;
|
||||
};
|
||||
|
||||
struct DEMOHEADER
|
||||
{
|
||||
int signature;
|
||||
short nVersion;
|
||||
int nBuild;
|
||||
int nInputCount;
|
||||
int nNetPlayers;
|
||||
short nMyConnectIndex;
|
||||
short nConnectHead;
|
||||
short connectPoints[8];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct DEMOCHAIN
|
||||
{
|
||||
DEMOCHAIN *pNext;
|
||||
char zName[BMAX_PATH];
|
||||
};
|
||||
|
||||
class CDemo {
|
||||
public:
|
||||
CDemo();
|
||||
~CDemo();
|
||||
bool Create(const char *);
|
||||
void Write(GINPUT *);
|
||||
void Close(void);
|
||||
bool SetupPlayback(const char *);
|
||||
void ProcessKeys(void);
|
||||
void Playback(void);
|
||||
void StopPlayback(void);
|
||||
void LoadDemoInfo(void);
|
||||
void NextDemo(void);
|
||||
void FlushInput(int nCount);
|
||||
void ReadInput(int nCount);
|
||||
bool at0; // record
|
||||
bool at1; // playback
|
||||
bool m_bLegacy;
|
||||
char at2;
|
||||
int at3;
|
||||
int hPFile;
|
||||
FILE *hRFile;
|
||||
int atb;
|
||||
DEMOHEADER atf;
|
||||
GAMEOPTIONS m_gameOptions;
|
||||
GINPUT at1aa[kInputBufferSize];
|
||||
const char **pzDemoFile;
|
||||
DEMOCHAIN *pFirstDemo;
|
||||
DEMOCHAIN *pCurrentDemo;
|
||||
int at59ef;
|
||||
};
|
||||
|
||||
extern CDemo gDemo;
|
1727
source/blood/src/dude.cpp
Normal file
1727
source/blood/src/dude.cpp
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue