mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-28 08:00:27 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efeda23627 | ||
|
|
465d462756 | ||
|
|
df22895b94 | ||
|
|
6b2160c876 | ||
|
|
088b44e2cc | ||
|
|
3f299610fc | ||
|
|
713e361d85 | ||
|
|
869075f47b | ||
|
|
a067c58b3d | ||
|
|
b16aaa5adc | ||
|
|
f4a412cc24 | ||
|
|
d83ad43b0b | ||
|
|
aa9847cf90 | ||
|
|
18a3658935 | ||
|
|
716a574abe | ||
|
|
e0dee12578 | ||
|
|
04b1e88077 | ||
|
|
51a2f7d479 | ||
|
|
2656000ce4 | ||
|
|
4ec10af1fd | ||
|
|
78cd0cf28b | ||
|
|
3e9d2bf89a | ||
|
|
ebe9795bba | ||
|
|
3f2c2f7aa4 | ||
|
|
583c2720e2 | ||
|
|
47d6843b70 | ||
|
|
25fd01c46b | ||
|
|
963b2a2bbd | ||
|
|
7274ceb0ff | ||
|
|
cb1c3c0b1c | ||
|
|
da5c35ec2b | ||
|
|
515beeafa7 | ||
|
|
37f5f64ef3 | ||
|
|
85c401496a | ||
|
|
07f7c557ce | ||
|
|
31278fba92 | ||
|
|
a32a9e8ae8 | ||
|
|
70dc1820db | ||
|
|
a760cb75a3 | ||
|
|
1d0b912f75 | ||
|
|
439e0718ce | ||
|
|
4c57ba6ef3 | ||
|
|
b4bae40da8 | ||
|
|
e04cbd57ea | ||
|
|
66664b7b46 | ||
|
|
546b90d75f | ||
|
|
14e83a52a4 | ||
|
|
dc9fec9d03 | ||
|
|
6d21d52d3e | ||
|
|
3afb87486b | ||
|
|
d0c0a55e6d | ||
|
|
1919b0efcb | ||
|
|
954d096261 | ||
|
|
7e150c7a8a | ||
|
|
77646bda78 | ||
|
|
e6848a3ab0 | ||
|
|
011f49616b | ||
|
|
e1be3c0fd1 | ||
|
|
3d950764a2 | ||
|
|
fe16f999d8 | ||
|
|
390c1d3f3d | ||
|
|
49b5c29c11 | ||
|
|
f86b495cc6 | ||
|
|
a4d0a96ce5 | ||
|
|
9d4ea75a18 | ||
|
|
38427fa3c5 | ||
|
|
7d369dec74 | ||
|
|
58bef33bc7 | ||
|
|
bd021b109c | ||
|
|
7e15c2ac1b | ||
|
|
3b1b994152 | ||
|
|
4e69d7a78a | ||
|
|
16166a36b5 | ||
|
|
bcbe7cd870 | ||
|
|
8dba91fbcc | ||
|
|
29fe5780e9 | ||
|
|
12686c0ab1 | ||
|
|
a21d712f54 | ||
|
|
2c7d18b331 | ||
|
|
e353673005 | ||
|
|
6b36bec8e9 | ||
|
|
1be50cdddf | ||
|
|
869b257bf8 | ||
|
|
f165ebf9a3 | ||
|
|
a6c168c289 | ||
|
|
0057a8273c | ||
|
|
876829a742 | ||
|
|
f4519325ce | ||
|
|
932367d061 | ||
|
|
79643d963e | ||
|
|
872b3f5d70 | ||
|
|
ac4138a763 | ||
|
|
0765537d29 | ||
|
|
f2f9ba9f83 | ||
|
|
20c1fab815 | ||
|
|
d3fb1331f8 | ||
|
|
13eafb9bf1 | ||
|
|
1ef61a6e3d | ||
|
|
0fb80a4ab5 | ||
|
|
981b12b63d | ||
|
|
508ee871b9 | ||
|
|
c293a52f7a | ||
|
|
acf2dd0ad1 | ||
|
|
32bee2602c | ||
|
|
d5ec17ec26 | ||
|
|
e53c6b55bf | ||
|
|
85da9fabdd | ||
|
|
e15440af5e | ||
|
|
26c2225a24 | ||
|
|
cd06dc0535 | ||
|
|
1b8ef411ee | ||
|
|
95466b810f | ||
|
|
0a41f3bb76 | ||
|
|
9b247a746c | ||
|
|
fcdde53774 | ||
|
|
279cfb364b | ||
|
|
3dcb2cad64 | ||
|
|
a199188ede | ||
|
|
8a84436d1b | ||
|
|
231553f574 | ||
|
|
37466cdffb | ||
|
|
3cc417151d | ||
|
|
d26718a711 | ||
|
|
0644bc2967 | ||
|
|
a2e4f1dc25 | ||
|
|
9c952ab49d | ||
|
|
aa52fe73a5 | ||
|
|
fee6390281 | ||
|
|
835ddb1de3 | ||
|
|
b58f031bcc | ||
|
|
3897a44ce6 | ||
|
|
1ec88142b9 | ||
|
|
70a5dde726 | ||
|
|
f684349c18 | ||
|
|
a08a9a4f10 | ||
|
|
f719b87e69 | ||
|
|
af1cbea966 | ||
|
|
f3f53947bc | ||
|
|
f0cc34cccf | ||
|
|
c4a1175ad0 | ||
|
|
333c452f44 | ||
|
|
5801af34bb | ||
|
|
da0c36cc88 | ||
|
|
d8d98ade6a | ||
|
|
c3157ad4d7 | ||
|
|
6f686cb7fa | ||
|
|
39981643a8 | ||
|
|
28bdd1b2b3 | ||
|
|
35f40e949b | ||
|
|
115b7b82aa | ||
|
|
d7c0ee47fe | ||
|
|
0559d643b7 | ||
|
|
8446a655bb | ||
|
|
01d098dab5 | ||
|
|
b6dd3914be | ||
|
|
c2e45710ad | ||
|
|
5da24a8ab5 | ||
|
|
ac6b274a4f | ||
|
|
f703ee2f26 | ||
|
|
70b8f9868e | ||
|
|
c69bafeb3f | ||
|
|
f7c8c745c4 | ||
|
|
861338b0fc | ||
|
|
499fe44bde | ||
|
|
ba74943844 | ||
|
|
21f631e733 | ||
|
|
b5c32a41de | ||
|
|
c9373cbc97 | ||
|
|
b5a73384d3 | ||
|
|
4f699f3b58 | ||
|
|
4ea598d76b | ||
|
|
7e6b0a1c2b | ||
|
|
d884512a76 | ||
|
|
71450fb36e | ||
|
|
4775f29194 | ||
|
|
d5d5c7a55d | ||
|
|
aa74934ae0 | ||
|
|
0534482c22 | ||
|
|
6fe1e86b31 | ||
|
|
47983481c9 | ||
|
|
383bc60ddb | ||
|
|
d834f08cad | ||
|
|
387ccd5cc3 | ||
|
|
0fb775cd60 | ||
|
|
f31ea39331 | ||
|
|
56cc3fff53 | ||
|
|
5f33a617ab | ||
|
|
b3da62f77e | ||
|
|
f1e5d02169 | ||
|
|
7cad7a4bd0 | ||
|
|
83a874e4fd | ||
|
|
6eab2ddd57 | ||
|
|
d944b4a21e | ||
|
|
58f0245e83 | ||
|
|
2f8382f100 | ||
|
|
167bd45a6a | ||
|
|
1e9decf193 | ||
|
|
459e13dc76 | ||
|
|
94e3d95d6c | ||
|
|
eeb9139024 | ||
|
|
486b6f40e5 | ||
|
|
d3fdaa060a | ||
|
|
766258e84b | ||
|
|
8213bf41a8 | ||
|
|
8843a8ee15 | ||
|
|
6bb09256c5 | ||
|
|
b2e6e1b56f | ||
|
|
6b402e5215 | ||
|
|
04baf673dc | ||
|
|
10b7651eff | ||
|
|
4f76d7291f | ||
|
|
1c2be68253 | ||
|
|
6c9d6940cc | ||
|
|
b719455b78 | ||
|
|
db16c8bea4 | ||
|
|
abdaecb28d |
No files matched your search
@@ -63,13 +63,6 @@ jobs:
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "CFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
# Temporary workaround for PowerPC as the 1.24.0 version doesn't check for altivec
|
||||
# Will use older versions until a new tag is created with this issue resolved
|
||||
if [ ${{ matrix.architecture.name }} != 'powerpc' ] && [ ${{ matrix.architecture.name }} != 'ppc64' ] && [ ${{ matrix.architecture.name }} != 'ppc64el' ]; then
|
||||
echo "OPENAL_REF=1.24.0" >> $GITHUB_ENV
|
||||
else
|
||||
echo "OPENAL_REF=1.23.1" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
###
|
||||
# SDL
|
||||
@@ -95,7 +88,7 @@ jobs:
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: ${{ env.OPENAL_REF }}
|
||||
ref: '1.24.1'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
@@ -249,7 +242,7 @@ jobs:
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.24.0'
|
||||
ref: '1.24.1'
|
||||
|
||||
# soft-oal build
|
||||
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
|
||||
@@ -352,12 +345,16 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
|
||||
{name: 'arm64', triple: 'arm64-apple-macos11'}
|
||||
#{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
|
||||
#{name: 'arm64', triple: 'arm64-apple-macos11'}
|
||||
#{name: 'x86_64', build_name: 'x86_64'},
|
||||
#{name: 'arm64', build_name: 'arm64'},
|
||||
# Compile into an universal binary
|
||||
{name: 'multiarch(arm64-x86_64)', build_name: 'arm64;x86_64' }
|
||||
]
|
||||
|
||||
name: "Building for platform macos-${{matrix.architecture.name}}"
|
||||
runs-on: "macos-14"
|
||||
runs-on: "macos-15"
|
||||
environment: ${{inputs.environment}}
|
||||
|
||||
steps:
|
||||
@@ -390,7 +387,7 @@ jobs:
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }}
|
||||
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}'
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on"
|
||||
###
|
||||
# OpenAL
|
||||
@@ -404,14 +401,14 @@ jobs:
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.24.0'
|
||||
ref: '1.24.1'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
@@ -429,7 +426,7 @@ jobs:
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include/AL' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
|
||||
@@ -38,8 +38,9 @@ jobs:
|
||||
'windows-x86-pdb',
|
||||
'windows-arm64',
|
||||
'windows-arm64-pdb',
|
||||
'macos-x86_64',
|
||||
'macos-arm64'
|
||||
#'macos-x86_64',
|
||||
#'macos-arm64',
|
||||
'macos-multiarch(arm64-x86_64)',
|
||||
]
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
@@ -56,8 +57,8 @@ jobs:
|
||||
path: ${{github.workspace}}/${{matrix.target_os}}
|
||||
|
||||
- name: Zip
|
||||
working-directory: ${{github.workspace}}/${{matrix.target_os}}
|
||||
run: zip -r ../${{ env.RELEASE_NAME }}.zip ./
|
||||
working-directory: '${{github.workspace}}/${{matrix.target_os}}'
|
||||
run: zip -r "../${{ env.RELEASE_NAME }}.zip" ./
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
|
||||
+34
-25
@@ -1,9 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(openmohaa)
|
||||
|
||||
include(TargetArch.cmake)
|
||||
include(misc/cmake/TargetArch.cmake)
|
||||
|
||||
target_architecture(TARGET_ARCH)
|
||||
list(LENGTH TARGET_ARCH TARGET_ARCH_COUNT)
|
||||
|
||||
set(USE_INTERNAL_LIBS ON)
|
||||
if(USE_SYSTEM_LIBS)
|
||||
@@ -13,12 +14,13 @@ endif()
|
||||
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
|
||||
option(USE_RENDERER_DLOPEN "Whether to compile the renderer as separate pluggable modules" OFF)
|
||||
option(TARGET_LOCAL_SYSTEM "Indicate that the project will be compiled and installed for the local system" OFF)
|
||||
|
||||
if(TARGET_GAME_TYPE)
|
||||
message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.")
|
||||
endif()
|
||||
|
||||
|
||||
set(TARGET_BASE_GAME "./")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
@@ -62,27 +64,39 @@ if(DEBUG_MEMORY)
|
||||
add_definitions(-D_DEBUG_MEM)
|
||||
endif()
|
||||
|
||||
IF("${TARGET_ARCH}" STREQUAL "i386")
|
||||
if("${TARGET_ARCH}" STREQUAL "i386")
|
||||
set(TARGET_ARCH_SUFFIX "x86")
|
||||
ELSE()
|
||||
else()
|
||||
set(TARGET_ARCH_SUFFIX ${TARGET_ARCH})
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
|
||||
message(STATUS "Architecture detected: ${TARGET_ARCH}")
|
||||
|
||||
message(STATUS "Architecture detected: ${TARGET_ARCH}, suffix set to ${TARGET_ARCH_SUFFIX}.")
|
||||
if(TARGET_LOCAL_SYSTEM)
|
||||
add_definitions(-DTARGET_LOCAL_SYSTEM)
|
||||
# As it targets the local system, no need to know about the architecture used
|
||||
set(TARGET_BIN_SUFFIX "")
|
||||
message(STATUS "Binary suffix will not be used as the local system is the target")
|
||||
elseif(${TARGET_ARCH_COUNT} GREATER 1)
|
||||
add_definitions(-DTARGET_MULTIPLE_ARCHITECTURES)
|
||||
set(TARGET_BIN_SUFFIX ".multiarch")
|
||||
message(STATUS "Multiple architectures were specified, suffix set to 'multiarch'.")
|
||||
else()
|
||||
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
|
||||
message(STATUS "Binary suffix set to '${TARGET_ARCH_SUFFIX}'.")
|
||||
endif()
|
||||
|
||||
IF(WIN32)
|
||||
if(WIN32)
|
||||
set(TARGET_PLATFORM_PREFIX "")
|
||||
message(STATUS "Using Win32 naming convention")
|
||||
ELSEIF(UNIX)
|
||||
elseif(UNIX)
|
||||
set(TARGET_PLATFORM_PREFIX "")
|
||||
message(STATUS "Using Unix naming convention")
|
||||
ELSE()
|
||||
else()
|
||||
set(TARGET_PLATFORM_PREFIX "")
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_compile_definitions(_DEBUG)
|
||||
|
||||
# NOTE: The following may mess up function importation
|
||||
@@ -91,10 +105,10 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
# message(STATUS "Enabling exports on Unix for backtrace")
|
||||
#endif()
|
||||
ELSE()
|
||||
else()
|
||||
# Non-debug builds
|
||||
add_compile_definitions(NDEBUG)
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# macOS doesn't search the executable path by default
|
||||
@@ -120,7 +134,7 @@ if(WIN32)
|
||||
set(LIB_INSTALL_SUBDIR ".")
|
||||
else()
|
||||
# Unix
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib)
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib${CMAKE_LIB_SUFFIX})
|
||||
set(BIN_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
set(LIB_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
@@ -171,23 +185,19 @@ if (NOT BUILD_NO_CLIENT)
|
||||
##
|
||||
## Client app
|
||||
##
|
||||
option(NO_MODERN_DMA "Use older sound-system" FALSE)
|
||||
|
||||
add_subdirectory("code/client")
|
||||
add_subdirectory("code/renderer")
|
||||
add_subdirectory("code/renderercommon")
|
||||
add_subdirectory("code/sdl")
|
||||
|
||||
#include("code/renderergl2/glsl/shaders.cmake")
|
||||
#file(GLOB_RECURSE SOURCES_RENDERER "code/sdl/*.c" "code/renderercommon/*.c" "code/renderergl2/*.c" "code/renderergl2/*.cpp")
|
||||
#list(FILTER SOURCES_RENDERER EXCLUDE REGEX "code/renderergl2/tr_subs.c")
|
||||
#list(FILTER SOURCES_RENDERER EXCLUDE REGEX "code/renderergl2/tr_model.c")
|
||||
|
||||
add_executable(openmohaa "misc/dummy.c")
|
||||
target_link_libraries(openmohaa PRIVATE syslib)
|
||||
target_link_libraries(openmohaa PRIVATE omohserver)
|
||||
target_link_libraries(openmohaa PRIVATE omohclient)
|
||||
target_link_libraries(openmohaa PRIVATE omohrenderer omohsdl)
|
||||
target_link_libraries(openmohaa PRIVATE omohrenderer)
|
||||
target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
|
||||
# Add the gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BIN_SUFFIX}")
|
||||
@@ -260,4 +270,3 @@ if(NOT TARGET uninstall)
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## Intro
|
||||
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts).
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** (including Spearhead and Breakthrough expansions) on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: an open-source version of MoH:AA (based on version 2.40) that is fully compatible with both the original game and expansions, in terms of network protocol, assets, and scripts. OpenMoHAA is compatible with both MOH:AA servers and clients (Spearhead and Breakthrough included).
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -26,11 +26,11 @@ The entire single-player campaign should work (Allied Assault, Spearhead and Bre
|
||||
|
||||
### Multiplayer
|
||||
|
||||
The Multiplayer part is almost fully stable.
|
||||
The Multiplayer part is almost fully stable, all game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
|
||||
|
||||
Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server. Bugs must be reported by creating a new [issue](https://github.com/openmoh/openmohaa/issues) on the OpenMoHAA GitHub project. Players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on a mohaa/mohaas/mohaab server.
|
||||
OpenMoHAA can be used to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server and players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on any server. If some bugs/strange behavior occurs, the best way to report them is by [creating a new issue](https://github.com/openmoh/openmohaa/issues) on the [OpenMoHAA GitHub](https://github.com/openmoh/openmohaa) project with the steps to reproduce (with eventually the problematic mods).
|
||||
|
||||
All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
|
||||
One of the big multiplayer features are bots. They were introduced for testing and for entertainment purposes so players can have fun alone. See [Configuring bots](docs/configuration/server.md#bots) in the dedicated server configuration documentation to set them up.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(Launcher)
|
||||
|
||||
set(LAUNCHER_SOURCES "${CMAKE_SOURCE_DIR}/code/Launcher/launch_main.cpp")
|
||||
|
||||
@@ -38,9 +38,9 @@ const char* targetGameList[] =
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<std::string> argumentList;
|
||||
#if !defined(DEDICATED) || !DEDICATED
|
||||
const char* programName = "openmohaa" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
const char* programName = "openmohaa" ARCH_SUFFIX DLL_SUFFIX EXE_EXT;
|
||||
#else
|
||||
const char* programName = "omohaaded" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
const char* programName = "omohaaded" ARCH_SUFFIX DLL_SUFFIX EXE_EXT;
|
||||
#endif
|
||||
|
||||
argumentList.push_back("+set");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(cgame)
|
||||
|
||||
# Shared source files for modules
|
||||
|
||||
@@ -3866,7 +3866,7 @@ void ClientGameCommandManager::PlaySound(
|
||||
}
|
||||
|
||||
if (!name || !soundAlias) {
|
||||
Com_Printf(
|
||||
cgi.DPrintf(
|
||||
"\nERROR PlaySound: %s needs an alias in ubersound.scr or uberdialog.scr - Please fix.\n",
|
||||
sound_name.c_str()
|
||||
);
|
||||
@@ -4066,7 +4066,7 @@ void ClientGameCommandManager::StopAliasChannel(Event *ev)
|
||||
}
|
||||
|
||||
if (!name || !soundAlias) {
|
||||
Com_Printf("\nERROR stopaliaschannel: couldn't find alias %s\n", sound_name.c_str());
|
||||
cgi.DPrintf("\nERROR stopaliaschannel: couldn't find alias %s\n", sound_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4145,8 +4145,8 @@ void ClientGameCommandManager::StopLoopSound(Event* ev)
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("\n\nClientGameCommandManager::StopLoopSound\n\n");
|
||||
current_centity->tikiLoopSound = NULL;
|
||||
cgi.DPrintf("\n\nClientGameCommandManager::StopLoopSound\n\n");
|
||||
current_centity->tikiLoopSound = (sfxHandle_t)0;
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -4265,7 +4265,7 @@ qboolean bLoadForMap(const char *psMapsBuffer, const char *name)
|
||||
}
|
||||
|
||||
if (!token || !token[0]) {
|
||||
Com_Printf("ERROR bLoadForMap: %s alias with empty maps specification.\n", name);
|
||||
cgi.DPrintf("ERROR bLoadForMap: %s alias with empty maps specification.\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5179,7 +5179,7 @@ void CG_ProcessInitCommands(dtiki_t *tiki, refEntity_t *ent)
|
||||
}
|
||||
|
||||
if (!commandManager.SelectProcessEvent(ev)) {
|
||||
Com_Printf(
|
||||
cgi.DPrintf(
|
||||
"^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name
|
||||
);
|
||||
}
|
||||
@@ -5225,7 +5225,7 @@ void CG_ProcessCacheInitCommands(dtiki_t *tiki)
|
||||
}
|
||||
|
||||
if (!commandManager.SelectProcessEvent(ev)) {
|
||||
Com_Printf(
|
||||
cgi.DPrintf(
|
||||
"^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name
|
||||
);
|
||||
}
|
||||
@@ -5298,7 +5298,7 @@ qboolean CG_ProcessEntityCommands(int frame, int anim, int entnum, refEntity_t *
|
||||
current_centity = cent;
|
||||
current_entity_number = entnum;
|
||||
current_tiki = ent->tiki;
|
||||
CG_AnimationDebugMessage(entnum, "Processing Ent Commands: Entity: %3d Anim:#(%i) Frame:#(%i)\n", anim, frame);
|
||||
CG_AnimationDebugMessage(entnum, "Processing Ent Commands: Entity: %3d Anim:#(%i) Frame:#(%i)\n", entnum, anim, frame);
|
||||
|
||||
for (i = 0; i < tikicmds.num_cmds; i++) {
|
||||
Event *ev;
|
||||
@@ -5840,7 +5840,7 @@ void ClientGameCommandManager::SetCurrentTiki(Event *ev)
|
||||
str tikiName;
|
||||
|
||||
if (ev->NumArgs() != 1) {
|
||||
Com_Printf("ERROR: settiki command takes 1 parameter.\n");
|
||||
cgi.DPrintf("ERROR: settiki command takes 1 parameter.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -705,5 +705,5 @@ int CG_WeaponCommandButtonBits(void)
|
||||
cg.iWeaponCommand = 0;
|
||||
}
|
||||
|
||||
return iShiftedWeaponCommand & WEAPON_COMMAND_MASK;
|
||||
return iShiftedWeaponCommand & GetWeaponCommandMask(cg_protocol >= PROTOCOL_MOHTA_MIN ? WEAPON_COMMAND_MAX_VER17 : WEAPON_COMMAND_MAX_VER6);
|
||||
}
|
||||
+121
-47
@@ -191,8 +191,8 @@ void CG_DrawDisconnect(void)
|
||||
}
|
||||
|
||||
handle = cgi.R_RegisterShader("gfx/2d/net.tga");
|
||||
w = cgi.R_GetShaderWidth(handle);
|
||||
h = cgi.R_GetShaderHeight(handle);
|
||||
w = cgi.R_GetShaderWidth(handle) * cgs.uiHiResScale[0];
|
||||
h = cgi.R_GetShaderHeight(handle) * cgs.uiHiResScale[1];
|
||||
x = ((float)cgs.glconfig.vidWidth - w) * 0.5;
|
||||
y = (float)cgs.glconfig.vidHeight - h;
|
||||
|
||||
@@ -331,7 +331,7 @@ static void CG_DrawPauseIcon()
|
||||
x = (cgs.glconfig.vidWidth - w) / 2.f;
|
||||
|
||||
cgi.R_SetColor(colorWhite);
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0, 0, 1, 1, handle);
|
||||
cgi.R_DrawStretchPic(x, y, w * cgs.uiHiResScale[0], h * cgs.uiHiResScale[1], 0, 0, 1, 1, handle);
|
||||
}
|
||||
|
||||
static void CG_DrawServerLag()
|
||||
@@ -362,8 +362,8 @@ static void CG_DrawServerLag()
|
||||
}
|
||||
|
||||
handle = cgi.R_RegisterShader("gfx/2d/slowserver");
|
||||
w = (float)cgi.R_GetShaderWidth(handle) / 4;
|
||||
h = (float)cgi.R_GetShaderHeight(handle) / 4;
|
||||
w = (float)cgi.R_GetShaderWidth(handle) * cgs.uiHiResScale[0] / 4;
|
||||
h = (float)cgi.R_GetShaderHeight(handle) * cgs.uiHiResScale[1] / 4;
|
||||
x = ((float)cgs.glconfig.vidWidth - w) / 2;
|
||||
y = (float)cgs.glconfig.vidHeight - h;
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0.0, 0.0, 1.0, 1.0, handle);
|
||||
@@ -580,11 +580,15 @@ void CG_HudDrawElements()
|
||||
int i;
|
||||
float fX, fY;
|
||||
float fWidth, fHeight;
|
||||
vec2_t virtualScale;
|
||||
|
||||
if (!cg_huddraw_force->integer && !cg_hud->integer) {
|
||||
return;
|
||||
}
|
||||
|
||||
virtualScale[0] = cgs.glconfig.vidWidth / 640.0;
|
||||
virtualScale[1] = cgs.glconfig.vidHeight / 480.0;
|
||||
|
||||
for (i = 0; i < MAX_HUDDRAW_ELEMENTS; i++) {
|
||||
if ((!cgi.HudDrawElements[i].hShader && !cgi.HudDrawElements[i].string[0])
|
||||
|| !cgi.HudDrawElements[i].vColor[3]) {
|
||||
@@ -597,6 +601,13 @@ void CG_HudDrawElements()
|
||||
fWidth = cgi.HudDrawElements[i].iWidth;
|
||||
fHeight = cgi.HudDrawElements[i].iHeight;
|
||||
|
||||
if (!cgi.HudDrawElements[i].bVirtualScreen) {
|
||||
fWidth *= cgs.uiHiResScale[0];
|
||||
fHeight *= cgs.uiHiResScale[1];
|
||||
fX *= cgs.uiHiResScale[0];
|
||||
fY *= cgs.uiHiResScale[1];
|
||||
}
|
||||
|
||||
if (cgi.HudDrawElements[i].iHorizontalAlign == HUD_ALIGN_X_CENTER) {
|
||||
if (cgi.HudDrawElements[i].bVirtualScreen) {
|
||||
fX += 320.0 - fWidth * 0.5;
|
||||
@@ -627,23 +638,28 @@ void CG_HudDrawElements()
|
||||
|
||||
cgi.R_SetColor(cgi.HudDrawElements[i].vColor);
|
||||
if (cgi.HudDrawElements[i].string[0]) {
|
||||
if (cgi.HudDrawElements[i].pFont) {
|
||||
fontheader_t* pFont = cgi.HudDrawElements[i].pFont;
|
||||
if (!pFont) {
|
||||
pFont = cgs.media.hudDrawFont;
|
||||
}
|
||||
|
||||
if (cgi.HudDrawElements[i].bVirtualScreen) {
|
||||
cgi.R_DrawString(
|
||||
cgi.HudDrawElements[i].pFont,
|
||||
pFont,
|
||||
cgi.LV_ConvertString(cgi.HudDrawElements[i].string),
|
||||
fX,
|
||||
fY,
|
||||
-1,
|
||||
cgi.HudDrawElements[i].bVirtualScreen
|
||||
virtualScale
|
||||
);
|
||||
} else {
|
||||
cgi.R_DrawString(
|
||||
cgs.media.hudDrawFont,
|
||||
pFont,
|
||||
cgi.LV_ConvertString(cgi.HudDrawElements[i].string),
|
||||
fX,
|
||||
fY,
|
||||
fX / cgs.uiHiResScale[0],
|
||||
fY / cgs.uiHiResScale[1],
|
||||
-1,
|
||||
cgi.HudDrawElements[i].bVirtualScreen
|
||||
cgs.uiHiResScale
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -734,7 +750,7 @@ void CG_DrawObjectives()
|
||||
vColor[0] = 0.2f;
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha * 0.75;
|
||||
cgi.R_SetColor(vColor);
|
||||
cgi.R_DrawStretchPic(fX, fY, 450.0, fWidth, 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader);
|
||||
cgi.R_DrawStretchPic(fX, fY, 450.0 * cgs.uiHiResScale[0], fWidth * cgs.uiHiResScale[1], 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader);
|
||||
|
||||
fX = 30.0;
|
||||
fY = fObjectivesTop + 10;
|
||||
@@ -743,11 +759,11 @@ void CG_DrawObjectives()
|
||||
vColor[2] = 1.0;
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
cgi.R_SetColor(vColor);
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, cgi.LV_ConvertString("Mission Objectives:"), fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, cgi.LV_ConvertString("Mission Objectives:"), fX, fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
fY = fY + 5.0;
|
||||
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY, -1, 0);
|
||||
fHeight = fObjectivesTop + 35;
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
fHeight = fObjectivesTop + 35 * cgs.uiHiResScale[1];
|
||||
|
||||
for (i = 0; i < MAX_OBJECTIVES; ++i) {
|
||||
qhandle_t hBoxShader;
|
||||
@@ -785,7 +801,14 @@ void CG_DrawObjectives()
|
||||
cgi.R_SetColor(vColor);
|
||||
fX = 55.0;
|
||||
fY = fHeight;
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, cgi.LV_ConvertString(cg.Objectives[i].text), 55.0, fHeight, -1, 0);
|
||||
cgi.R_DrawString(
|
||||
cgs.media.objectiveFont,
|
||||
cgi.LV_ConvertString(cg.Objectives[i].text),
|
||||
55.0,
|
||||
fY / cgs.uiHiResScale[1],
|
||||
-1,
|
||||
cgs.uiHiResScale
|
||||
);
|
||||
|
||||
fX = 30.0;
|
||||
fY = fHeight;
|
||||
@@ -794,9 +817,19 @@ void CG_DrawObjectives()
|
||||
vColor[2] = 1.0;
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
cgi.R_SetColor(vColor);
|
||||
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hBoxShader);
|
||||
cgi.R_DrawStretchPic(
|
||||
fX * cgs.uiHiResScale[0],
|
||||
fY,
|
||||
16.0 * cgs.uiHiResScale[0],
|
||||
16.0 * cgs.uiHiResScale[1],
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
hBoxShader
|
||||
);
|
||||
|
||||
fHeight += iNumLines[i] * 12 + 25;
|
||||
fHeight += iNumLines[i] * 12 + 25 * cgs.uiHiResScale[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,7 +853,17 @@ void CG_DrawPlayerTeam()
|
||||
|
||||
if (handle) {
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(96.0, cgs.glconfig.vidHeight - 46, 24.0, 24.0, 0.0, 0.0, 1.0, 1.0, handle);
|
||||
cgi.R_DrawStretchPic(
|
||||
96.0 * cgs.uiHiResScale[0],
|
||||
cgs.glconfig.vidHeight - 46 * cgs.uiHiResScale[1],
|
||||
24.0 * cgs.uiHiResScale[0],
|
||||
24.0 * cgs.uiHiResScale[1],
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
handle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,13 +905,12 @@ void CG_DrawPlayerEntInfo()
|
||||
|
||||
if (handle) {
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawStretchPic(56.0, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, handle);
|
||||
fX = 56.0 + 24.0;
|
||||
cgi.R_DrawStretchPic(fX, fY, 16.0 * cgs.uiHiResScale[0], 16.0 * cgs.uiHiResScale[1], 0.0, 0.0, 1.0, 1.0, handle);
|
||||
}
|
||||
|
||||
cgi.R_SetColor(color);
|
||||
cgi.R_DrawString(cgs.media.hudDrawFont, (char *)pszName, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.hudDrawFont, va("%i", cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]), fX, fY + 20.0, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.hudDrawFont, (char *)pszName, fX / cgs.uiHiResScale[0] + 24.0, fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
cgi.R_DrawString(cgs.media.hudDrawFont, va("%i", cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]), fX / cgs.uiHiResScale[0] + 24.0, fY / cgs.uiHiResScale[1] + 20.0, -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
void CG_UpdateAttackerDisplay()
|
||||
@@ -907,7 +949,17 @@ void CG_UpdateAttackerDisplay()
|
||||
|
||||
if (handle) {
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawStretchPic(56.0, fY, 24.0, 24.0, 0.0, 0.0, 1.0, 1.0, handle);
|
||||
cgi.R_DrawStretchPic(
|
||||
56.0 * cgs.uiHiResScale[0],
|
||||
fY,
|
||||
24.0 * cgs.uiHiResScale[0],
|
||||
24.0 * cgs.uiHiResScale[1],
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
handle
|
||||
);
|
||||
}
|
||||
|
||||
if ((cg.snap->ps.stats[STAT_TEAM] == TEAM_ALLIES || cg.snap->ps.stats[STAT_TEAM] == TEAM_AXIS)
|
||||
@@ -921,7 +973,7 @@ void CG_UpdateAttackerDisplay()
|
||||
color[2] = 0.5;
|
||||
}
|
||||
|
||||
fX = 56.0 + 32.0;
|
||||
fX = 56.0;
|
||||
} else {
|
||||
color[0] = 1.0;
|
||||
color[1] = 0.5;
|
||||
@@ -929,7 +981,7 @@ void CG_UpdateAttackerDisplay()
|
||||
}
|
||||
|
||||
cgi.R_SetColor(color);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszName, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszName, fX / cgs.uiHiResScale[0] + 32.0, fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
void CG_UpdateCountdown()
|
||||
@@ -1043,7 +1095,7 @@ void CG_DrawInstantMessageMenu()
|
||||
x = 8.0;
|
||||
y = ((float)cgs.glconfig.vidHeight - h) * 0.5;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0.0, 0.0, 1.0, 1.0, handle);
|
||||
cgi.R_DrawStretchPic(x * cgs.uiHiResScale[0], y, w * cgs.uiHiResScale[0], h * cgs.uiHiResScale[1], 0.0, 0.0, 1.0, 1.0, handle);
|
||||
}
|
||||
|
||||
void CG_DrawSpectatorView_ver_15()
|
||||
@@ -1069,7 +1121,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = cgs.glconfig.vidHeight - 64.0;
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, qfalse);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
if (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW) {
|
||||
@@ -1085,7 +1137,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 40.0;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
|
||||
@@ -1096,7 +1148,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 24.0;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
if (!(cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
|
||||
@@ -1109,10 +1161,10 @@ void CG_DrawSpectatorView_ver_15()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 24.0;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
if ((cg.predicted_player_state.pm_flags & 0x80) != 0 && cg.snap && cg.snap->ps.stats[STAT_INFOCLIENT] != -1) {
|
||||
if ((cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW) != 0 && cg.snap && cg.snap->ps.stats[STAT_INFOCLIENT] != -1) {
|
||||
int iClientNum;
|
||||
qhandle_t hShader;
|
||||
vec4_t color;
|
||||
@@ -1130,7 +1182,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) - 16) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 80.0;
|
||||
cgi.R_SetColor(color);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, buf, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, buf, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
|
||||
if (cg.clientinfo[iClientNum].team == TEAM_ALLIES) {
|
||||
hShader = cgi.R_RegisterShader("textures/hud/allies");
|
||||
@@ -1139,9 +1191,18 @@ void CG_DrawSpectatorView_ver_15()
|
||||
}
|
||||
|
||||
if (hShader) {
|
||||
fX -= 20.0;
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hShader);
|
||||
cgi.R_DrawStretchPic(
|
||||
fX - 20.0 * cgs.uiHiResScale[0],
|
||||
fY,
|
||||
16.0 * cgs.uiHiResScale[0],
|
||||
16.0 * cgs.uiHiResScale[1],
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
hShader
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1176,7 +1237,7 @@ void CG_DrawSpectatorView_ver_6()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 40.0;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
|
||||
if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
|
||||
cgi.Key_GetKeysForCommand("+moveup", &iKey1, &iKey2);
|
||||
@@ -1190,7 +1251,7 @@ void CG_DrawSpectatorView_ver_6()
|
||||
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5;
|
||||
fY = (float)cgs.glconfig.vidHeight - 24.0;
|
||||
cgi.R_SetColor(0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,6 +1294,9 @@ void CG_DrawCrosshair()
|
||||
return;
|
||||
}
|
||||
|
||||
// Fixed in OPM: R_RegisterShaderNoMip
|
||||
// Use R_RegisterShaderNoMip, as it's UI stuff
|
||||
|
||||
if (cgs.gametype != GT_FFA) {
|
||||
AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL);
|
||||
|
||||
@@ -1260,23 +1324,23 @@ void CG_DrawCrosshair()
|
||||
|| ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) {
|
||||
// friend
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair_friend->string);
|
||||
shader = cgi.R_RegisterShaderNoMip(cg_crosshair_friend->string);
|
||||
}
|
||||
} else {
|
||||
// enemy
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FFA
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,7 +1351,17 @@ void CG_DrawCrosshair()
|
||||
y = (cgs.glconfig.vidHeight - height) * 0.5f;
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, shader);
|
||||
cgi.R_DrawStretchPic(
|
||||
x,
|
||||
y,
|
||||
width * cgs.uiHiResScale[0],
|
||||
height * cgs.uiHiResScale[1],
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
shader
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1324,7 +1398,7 @@ void CG_DrawVote()
|
||||
cgi.R_SetColor(NULL);
|
||||
|
||||
text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, cgs.uiHiResScale);
|
||||
|
||||
y += 12;
|
||||
|
||||
@@ -1338,7 +1412,7 @@ void CG_DrawVote()
|
||||
percentNo,
|
||||
cgi.LV_ConvertString("Undecided"),
|
||||
percentUndecided);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, cgs.uiHiResScale);
|
||||
|
||||
if (cg.snap && !cg.snap->ps.voted) {
|
||||
col[0] = 0.5;
|
||||
@@ -1350,12 +1424,12 @@ void CG_DrawVote()
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, cgs.uiHiResScale);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2.");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, cgs.uiHiResScale);
|
||||
cgi.R_SetColor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,6 +380,7 @@ extern "C" {
|
||||
float screenXScale; // derived from glconfig
|
||||
float screenYScale;
|
||||
float screenXBias;
|
||||
vec2_t uiHiResScale;
|
||||
|
||||
int serverCommandSequence; // reliable command stream counter
|
||||
int processedSnapshotNum; // the number of snapshots cgame has requested
|
||||
@@ -505,9 +506,15 @@ extern "C" {
|
||||
extern cvar_t *cg_shadowdebug;
|
||||
extern cvar_t *ui_timemessage;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
extern cvar_t *cg_fov;
|
||||
|
||||
//
|
||||
// cg_main.c
|
||||
//
|
||||
qboolean CG_UseLargeLightmaps(const char* mapName);
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly);
|
||||
const char *CG_ConfigString(int index);
|
||||
void CG_AddToTeamChat(const char *str);
|
||||
|
||||
@@ -112,6 +112,11 @@ cvar_t *cg_shadowscount;
|
||||
cvar_t *cg_shadowdebug;
|
||||
cvar_t *ui_timemessage;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
cvar_t *cg_fov;
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_RegisterCvars
|
||||
@@ -203,6 +208,31 @@ void CG_RegisterCvars(void)
|
||||
// see if we are also running the server on this machine
|
||||
temp = cgi.Cvar_Get("sv_running", "0", 0);
|
||||
cgs.localServer = temp->integer;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
|
||||
cg_fov = cgi.Cvar_Get("cg_fov", "80", CVAR_ARCHIVE);
|
||||
}
|
||||
/*
|
||||
===============
|
||||
CG_UseLargeLightmaps
|
||||
|
||||
Added in 2.0
|
||||
Returns true if the standard BSP file should be used, false if the smaller lightmap BSP file should be used
|
||||
===============
|
||||
*/
|
||||
qboolean CG_UseLargeLightmaps(const char* mapName) {
|
||||
char buffer[MAX_QPATH];
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "maps/%s_sml.bsp", mapName);
|
||||
|
||||
if (cgi.FS_ReadFile(buffer, NULL, qtrue) == -1) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return cgi.Cvar_Get("r_largemap", "0", 0)->integer;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -570,6 +600,7 @@ void CG_GetRendererConfig(void)
|
||||
cgi.GetGlconfig(&cgs.glconfig);
|
||||
cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
|
||||
cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
|
||||
cgi.UI_GetHighResolutionScale(cgs.uiHiResScale);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1200,7 +1200,9 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
if (!cg.pLastPlayerWorldModel || cg.pLastPlayerWorldModel != model.tiki) {
|
||||
qhandle_t hModel;
|
||||
char fpsname[128];
|
||||
|
||||
COM_StripExtension(model.tiki->a->name, fpsname, sizeof(fpsname));
|
||||
Q_strcat(fpsname, sizeof(fpsname), "_fps.tik");
|
||||
|
||||
hModel = cgi.R_RegisterModel(fpsname);
|
||||
if (hModel) {
|
||||
|
||||
+17
-3
@@ -330,8 +330,18 @@ static void CG_InterpolatePlayerStateCamera(void)
|
||||
//
|
||||
VectorCopy(cg.predicted_player_state.camera_angles, cg.camera_angles);
|
||||
VectorCopy(cg.predicted_player_state.camera_origin, cg.camera_origin);
|
||||
cg.camera_fov = cg.predicted_player_state.fov;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
// Use the specified fov specified by the server
|
||||
// when zooming
|
||||
//
|
||||
if (cg.predicted_player_state.stats[STAT_INZOOM]) {
|
||||
cg.camera_fov = cg.predicted_player_state.fov;
|
||||
} else {
|
||||
cg.camera_fov = cg_fov->value;
|
||||
}
|
||||
|
||||
// if the next frame is a teleport, we can't lerp to it
|
||||
if (cg.nextFrameCameraCut) {
|
||||
return;
|
||||
@@ -343,8 +353,12 @@ static void CG_InterpolatePlayerStateCamera(void)
|
||||
|
||||
f = (float)(cg.time - prev->serverTime) / (next->serverTime - prev->serverTime);
|
||||
|
||||
// interpolate fov
|
||||
cg.camera_fov = prev->ps.fov + f * (next->ps.fov - prev->ps.fov);
|
||||
if (cg.predicted_player_state.stats[STAT_INZOOM]) {
|
||||
// interpolate fov
|
||||
cg.camera_fov = prev->ps.fov + f * (next->ps.fov - prev->ps.fov);
|
||||
} else {
|
||||
cg.camera_fov = cg_fov->value;
|
||||
}
|
||||
|
||||
if (!(cg.snap->ps.pm_flags & PMF_CAMERA_VIEW)) {
|
||||
return;
|
||||
|
||||
@@ -312,12 +312,12 @@ functions exported to the main executable
|
||||
); // 0 = white
|
||||
fontheader_t *(*R_LoadFont)(const char *name);
|
||||
void (*R_DrawString)(
|
||||
fontheader_t *font, const char *text, float x, float y, int maxLen, qboolean virtualScreen
|
||||
fontheader_t *font, const char *text, float x, float y, int maxLen, const float *pvVirtualScreen
|
||||
);
|
||||
refEntity_t *(*R_GetRenderEntity)(int entityNumber);
|
||||
void (*R_ModelBounds)(clipHandle_t model, vec3_t mins, vec3_t maxs);
|
||||
float (*R_ModelRadius)(clipHandle_t model);
|
||||
float (*R_Noise)(float x, float y, float z, float t);
|
||||
float (*R_Noise)(float x, float y, float z, double t);
|
||||
void (*R_DebugLine)(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
|
||||
baseshader_t *(*GetShader)(int shaderNum);
|
||||
// =========== Swipes =============
|
||||
@@ -363,6 +363,7 @@ functions exported to the main executable
|
||||
int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen);
|
||||
// Added in 2.0
|
||||
float (*UI_GetObjectivesTop)(void);
|
||||
void (*UI_GetHighResolutionScale)(vec2_t scale);
|
||||
|
||||
int (*Key_StringToKeynum)(const char *str);
|
||||
const char *(*Key_KeynumToBindString)(int keyNum);
|
||||
|
||||
@@ -190,8 +190,12 @@ void CG_ParseServerinfo(void)
|
||||
Q_strncpyz(map, mapname, sizeof(map));
|
||||
}
|
||||
|
||||
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
|
||||
|
||||
if (CG_UseLargeLightmaps(mapname)) {
|
||||
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
|
||||
} else {
|
||||
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s_sml.bsp", map);
|
||||
}
|
||||
|
||||
// hide/show huds
|
||||
if (cgs.gametype) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_timelimit\n");
|
||||
@@ -461,6 +465,10 @@ void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
|
||||
static const char *whiteListedVariables[] = {
|
||||
"r_fastsky", // some mods set this variable to make the sky uniform
|
||||
"ui_hud",
|
||||
"subtitle0",
|
||||
"subtitle1",
|
||||
"subtitle2",
|
||||
"subtitle3"
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -120,7 +120,7 @@ void CG_MessageSingleClient_f(void)
|
||||
|
||||
// copy the rest
|
||||
for (i = 2; i < cgi.Argc(); i++) {
|
||||
sString += va("%s", cgi.Argv(i));
|
||||
sString += va(" %s", cgi.Argv(i));
|
||||
}
|
||||
|
||||
sString += "\n";
|
||||
|
||||
+19
-3
@@ -298,7 +298,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
|
||||
VectorCopy(origin, vOldOrigin);
|
||||
|
||||
if (!cg.predicted_player_state.walking || !(cg.predicted_player_state.pm_flags & PMF_FROZEN)) {
|
||||
if (!cg.predicted_player_state.walking || (!(cg.predicted_player_state.pm_flags & PMF_FROZEN) && !(cg.predicted_player_state.pm_flags & PMF_NO_MOVE))) {
|
||||
VectorCopy(cg.predicted_player_state.velocity, vVelocity);
|
||||
} else {
|
||||
//
|
||||
@@ -485,9 +485,16 @@ static int CG_CalcFov(void)
|
||||
int contents;
|
||||
float fov_x, fov_y;
|
||||
int inwater;
|
||||
float fov_ratio;
|
||||
|
||||
fov_x = cg.camera_fov;
|
||||
x = cg.refdef.width / tan(fov_x / 360 * M_PI);
|
||||
fov_ratio = (float)cg.refdef.width / (float)cg.refdef.height * (3.0 / 4.0);
|
||||
if (fov_ratio == 1) {
|
||||
fov_x = cg.camera_fov;
|
||||
} else {
|
||||
fov_x = RAD2DEG(atan(tan(DEG2RAD(cg.camera_fov / 2.0)) * fov_ratio)) * 2.0;
|
||||
}
|
||||
|
||||
x = cg.refdef.width / tan(fov_x / 360 * M_PI);
|
||||
fov_y = atan2(cg.refdef.height, x);
|
||||
fov_y = fov_y * 360 / M_PI;
|
||||
|
||||
@@ -840,6 +847,15 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
// no entities should be marked as interpolating
|
||||
}
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
// Clamp the fov to avoid artifacts
|
||||
if (cg_fov->value < 65) {
|
||||
cgi.Cvar_Set("cg_fov", "65");
|
||||
} else if (cg_fov->value > 120) {
|
||||
cgi.Cvar_Set("cg_fov", "120");
|
||||
}
|
||||
|
||||
// update cg.predicted_player_state
|
||||
CG_PredictPlayerState();
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(omohclient)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
option(NO_OPENAL "Use older sound-system" FALSE)
|
||||
project(omohclient)
|
||||
|
||||
add_subdirectory("../cgame" "./cgame")
|
||||
|
||||
@@ -11,16 +10,15 @@ file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
|
||||
# Made as an interface and not static, as static only links used methods
|
||||
add_library(omohclient INTERFACE)
|
||||
target_compile_definitions(omohclient INTERFACE APP_MODULE)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
|
||||
target_compile_features(omohclient INTERFACE cxx_nullptr)
|
||||
target_compile_features(omohclient INTERFACE c_variadic_macros)
|
||||
target_link_libraries(omohclient INTERFACE omohsdl)
|
||||
target_link_libraries(omohclient INTERFACE omohsdl_client)
|
||||
target_link_libraries(omohclient INTERFACE gcd)
|
||||
|
||||
# Sound stuff
|
||||
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
|
||||
|
||||
if (NOT NO_OPENAL)
|
||||
if (NOT NO_MODERN_DMA)
|
||||
# Use OpenAL
|
||||
find_package(OpenAL REQUIRED)
|
||||
|
||||
@@ -31,7 +29,13 @@ if (NOT NO_OPENAL)
|
||||
else()
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
|
||||
endif()
|
||||
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
|
||||
|
||||
if(NOT USE_SYSTEM_LIBS)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
|
||||
else()
|
||||
# Link against system OpenAL
|
||||
target_link_libraries(omohclient INTERFACE OpenAL::OpenAL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$")
|
||||
|
||||
@@ -774,6 +774,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->UI_HideMenu = UI_HideMenu;
|
||||
cgi->UI_FontStringWidth = CL_FontStringWidth;
|
||||
cgi->UI_GetObjectivesTop = UI_GetObjectivesTop;
|
||||
cgi->UI_GetHighResolutionScale = UI_GetHighResolutionScale;
|
||||
cgi->Key_StringToKeynum = Key_StringToKeynum;
|
||||
cgi->Key_KeynumToBindString = Key_KeynumToBindString;
|
||||
cgi->Key_GetKeysForCommand = Key_GetKeysForCommand;
|
||||
@@ -922,7 +923,13 @@ void CL_InitCGame( void ) {
|
||||
// find the current mapname
|
||||
info = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ];
|
||||
mapname = Info_ValueForKey( info, "mapname" );
|
||||
Com_sprintf( cl.mapname, sizeof( cl.mapname ), "maps/%s.bsp", mapname );
|
||||
|
||||
if (CL_UseLargeLightmap(mapname)) {
|
||||
Com_sprintf(cl.mapname, sizeof(cl.mapname), "maps/%s.bsp", mapname);
|
||||
} else {
|
||||
// Added in 2.0
|
||||
Com_sprintf(cl.mapname, sizeof(cl.mapname), "maps/%s_sml.bsp", mapname);
|
||||
}
|
||||
|
||||
S_BeginRegistration();
|
||||
CL_ShutdownCGame();
|
||||
@@ -937,10 +944,17 @@ void CL_InitCGame( void ) {
|
||||
CL_InitClientSavedData();
|
||||
}
|
||||
|
||||
// init for this gamestate
|
||||
// use the lastExecutedServerCommand instead of the serverCommandSequence
|
||||
// otherwise server commands sent just before a gamestate are dropped
|
||||
cge->CG_Init( &cgi, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum );
|
||||
if (cl.snap.valid) {
|
||||
// init for this gamestate
|
||||
// use the lastExecutedServerCommand instead of the serverCommandSequence
|
||||
// otherwise server commands sent just before a gamestate are dropped
|
||||
cge->CG_Init(&cgi, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum);
|
||||
} else {
|
||||
// executing client commands from previous map/server might be an issue, some commands might be cs commands,
|
||||
// like old CS_SYSTEMINFO configstrings which still contain the sv_serverId from previous map.
|
||||
// It would cause the client to lose the game state number
|
||||
cge->CG_Init(&cgi, clc.serverMessageSequence, clc.serverCommandSequence, clc.clientNum);
|
||||
}
|
||||
|
||||
ClearNewConfigFlag();
|
||||
TIKI_FinishLoad();
|
||||
|
||||
@@ -295,7 +295,7 @@ void UI_DoInventory(qboolean activate_mouse)
|
||||
if (client_inv.align == INV_ALIGN_RIGHT) {
|
||||
s_main_inv->InitFrame(
|
||||
NULL,
|
||||
client_inv.horizoffset + cls.glconfig.vidWidth - client_inv.typewidth,
|
||||
client_inv.horizoffset + uid.vidWidth - client_inv.typewidth,
|
||||
client_inv.vertoffset,
|
||||
client_inv.typewidth,
|
||||
client_inv.typeheight * client_inv.types.NumObjects(),
|
||||
|
||||
+199
-72
@@ -29,14 +29,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/localization.h"
|
||||
#include "../qcommon/bg_compat.h"
|
||||
#include "../sys/sys_local.h"
|
||||
#ifdef USE_RENDERER_DLL
|
||||
#include "../sys/sys_loadlib.h"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "../sys/sys_loadlib.h"
|
||||
}
|
||||
|
||||
#include "../gamespy/gcdkey/gcdkeyc.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
cvar_t* cl_renderer;
|
||||
#endif
|
||||
|
||||
cvar_t *cl_nodelta;
|
||||
cvar_t *cl_debugMove;
|
||||
|
||||
@@ -130,19 +135,14 @@ clientGameExport_t *cge;
|
||||
|
||||
// Structure containing functions exported from refresh DLL
|
||||
refexport_t re;
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
static void *rendererLib = NULL;
|
||||
#endif
|
||||
|
||||
qboolean camera_reset;
|
||||
qboolean camera_active;
|
||||
vec3_t camera_offset;
|
||||
|
||||
#ifdef USE_RENDERER_DLL
|
||||
// su44: for plugable renderer system
|
||||
refexport_t* (*DGetRefAPI)(int apiVersion, refimport_t * rimp) = NULL;
|
||||
static cvar_t *cl_renderer = NULL;
|
||||
static void *rendererLib = NULL;
|
||||
#endif // USE_RENDERER_DLL
|
||||
|
||||
|
||||
ping_t cl_pinglist[MAX_PINGREQUESTS];
|
||||
|
||||
typedef struct serverStatus_s
|
||||
@@ -172,6 +172,26 @@ void CL_ServerStatusResponse( netadr_t from, msg_t *msg );
|
||||
|
||||
static qboolean cl_bCLSystemStarted = qfalse;
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_UseLargeLightmap
|
||||
|
||||
Added in 2.0
|
||||
Returns true if the standard BSP file should be used, false if the smaller lightmap BSP file should be used
|
||||
===============
|
||||
*/
|
||||
qboolean CL_UseLargeLightmap(const char* mapName) {
|
||||
char buffer[MAX_QPATH];
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "maps/%s_sml.bsp", mapName);
|
||||
|
||||
if (FS_ReadFileEx(buffer, NULL, qtrue) == -1) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return Cvar_Get("r_largemap", "0", 0)->integer;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_CDDialog
|
||||
@@ -782,9 +802,10 @@ void CL_ShutdownAll(qboolean shutdownRef) {
|
||||
TIKI_FreeAll();
|
||||
|
||||
// shutdown the renderer
|
||||
if ( re.Shutdown ) {
|
||||
re.Shutdown( qfalse ); // don't destroy window or context
|
||||
}
|
||||
if(shutdownRef)
|
||||
CL_ShutdownRef();
|
||||
else if(re.Shutdown)
|
||||
re.Shutdown(qfalse); // don't destroy window or context
|
||||
|
||||
cls.uiStarted = qfalse;
|
||||
cls.cgameStarted = qfalse;
|
||||
@@ -1560,19 +1581,24 @@ void CL_Vid_Restart_f( void ) {
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
// shutdown the UI
|
||||
//CL_ShutdownUI();
|
||||
// shutdown the renderer and clear the renderer interface
|
||||
CL_ShutdownRef();
|
||||
CL_ShutdownRef();
|
||||
|
||||
cls.rendererRegistered = qfalse;
|
||||
|
||||
// shutdown the CGame
|
||||
CL_ShutdownCGame();
|
||||
// initialize the renderer interface
|
||||
CL_InitRef();
|
||||
// initialize the UI
|
||||
//CL_InitializeUI();
|
||||
// initialize the ui library
|
||||
UI_ResolutionChange();
|
||||
// clear aliases
|
||||
Alias_Clear();
|
||||
|
||||
cls.rendererRegistered = qfalse;
|
||||
|
||||
// unpause so the cgame definately gets a snapshot and renders a frame
|
||||
Com_Unpause();
|
||||
|
||||
@@ -2554,7 +2580,7 @@ void CL_CheckUserinfo( void ) {
|
||||
// send a reliable userinfo update if needed
|
||||
if(cvar_modifiedFlags & CVAR_USERINFO)
|
||||
{
|
||||
if (Com_SanitizeName(name->string, szSanitizedName)) {
|
||||
if (Com_SanitizeName(name->string, szSanitizedName, sizeof(szSanitizedName))) {
|
||||
Cvar_Set("name", szSanitizedName);
|
||||
}
|
||||
|
||||
@@ -2564,6 +2590,10 @@ void CL_CheckUserinfo( void ) {
|
||||
}
|
||||
|
||||
void CL_SetFrameNumber(int frameNumber) {
|
||||
if (!re.SetFrameNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
re.SetFrameNumber(frameNumber);
|
||||
}
|
||||
|
||||
@@ -2789,15 +2819,15 @@ CL_ShutdownRef
|
||||
============
|
||||
*/
|
||||
void CL_ShutdownRef( void ) {
|
||||
if ( !re.Shutdown ) {
|
||||
return;
|
||||
if ( re.Shutdown ) {
|
||||
re.Shutdown( qtrue );
|
||||
}
|
||||
re.Shutdown( qtrue );
|
||||
|
||||
Com_Memset( &re, 0, sizeof( re ) );
|
||||
#ifdef USE_RENDERER_DLL
|
||||
// su44: remember to unload renderer library
|
||||
if(rendererLib) {
|
||||
Sys_UnloadLibrary(rendererLib);
|
||||
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
if ( rendererLib ) {
|
||||
Sys_UnloadLibrary( rendererLib );
|
||||
rendererLib = NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -2974,22 +3004,105 @@ void CL_CG_EndTiki( dtiki_t *tiki ) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_CG_EndTiki
|
||||
============
|
||||
*/
|
||||
extern "C"
|
||||
int CL_ScaledMilliseconds(void) {
|
||||
return Sys_Milliseconds()*com_timescale->value;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefFS_WriteFile
|
||||
============
|
||||
*/
|
||||
void CL_RefFS_WriteFile(const char* qpath, const void* buffer, int size) {
|
||||
FS_WriteFile(qpath, buffer, size);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefFS_ListFiles
|
||||
============
|
||||
*/
|
||||
char** CL_RefFS_ListFiles(const char* name, const char* extension, int* numfilesfound) {
|
||||
return FS_ListFiles(name, extension, qtrue, numfilesfound);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefCIN_UploadCinematic
|
||||
============
|
||||
*/
|
||||
void CL_RefCIN_UploadCinematic(int handle) {
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefTIKI_GetNumChannels
|
||||
============
|
||||
*/
|
||||
int CL_RefTIKI_GetNumChannels(dtiki_t* tiki) {
|
||||
return tiki->m_boneList.NumChannels();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefTIKI_GetLocalChannel
|
||||
============
|
||||
*/
|
||||
int CL_RefTIKI_GetLocalChannel(dtiki_t* tiki, int channel) {
|
||||
return tiki->m_boneList.LocalChannel(channel);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefTIKI_GetLocalFromGlobal
|
||||
============
|
||||
*/
|
||||
int CL_RefTIKI_GetLocalFromGlobal(dtiki_t* tiki, int channel) {
|
||||
return tiki->m_boneList.GetLocalFromGlobal(channel);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefSKEL_GetMorphWeightFrame
|
||||
============
|
||||
*/
|
||||
int CL_RefSKEL_GetMorphWeightFrame(void* skeletor, int index, float time, int* data) {
|
||||
return ((skeletor_c*)skeletor)->GetMorphWeightFrame(index, time, data);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefSKEL_GetBoneParent
|
||||
============
|
||||
*/
|
||||
int CL_RefSKEL_GetBoneParent(void* skeletor, int boneIndex) {
|
||||
return ((skeletor_c*)skeletor)->GetBoneParent(boneIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_GetRefSequence
|
||||
============
|
||||
*/
|
||||
int CL_GetRefSequence(void) {
|
||||
return cls.refSequence;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_IsRendererLoaded
|
||||
============
|
||||
*/
|
||||
qboolean CL_IsRendererLoaded(void) {
|
||||
return re.Shutdown != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_InitRef
|
||||
@@ -2998,12 +3111,40 @@ CL_InitRef
|
||||
void CL_InitRef( void ) {
|
||||
refimport_t ri;
|
||||
refexport_t *ret;
|
||||
#ifdef USE_RENDERER_DLL
|
||||
char dllName[256];
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
GetRefAPI_t GetRefAPI;
|
||||
char dllName[MAX_OSPATH];
|
||||
#endif
|
||||
|
||||
Com_Printf( "----- Initializing Renderer ----\n" );
|
||||
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
Com_sprintf(dllName, sizeof(dllName), "renderer_%s" ARCH_SUFFIX DLL_SUFFIX DLL_EXT, cl_renderer->string);
|
||||
|
||||
if(!(rendererLib = Sys_LoadDll(dllName, qfalse)) && strcmp(cl_renderer->string, cl_renderer->resetString))
|
||||
{
|
||||
Com_Printf("failed:\n\"%s\"\n", Sys_LibraryError());
|
||||
Cvar_ForceReset("cl_renderer");
|
||||
|
||||
Com_sprintf(dllName, sizeof(dllName), "renderer_opengl1" ARCH_SUFFIX DLL_SUFFIX DLL_EXT);
|
||||
rendererLib = Sys_LoadDll(dllName, qfalse);
|
||||
}
|
||||
|
||||
if(!rendererLib)
|
||||
{
|
||||
Com_Printf("failed:\n\"%s\"\n", Sys_LibraryError());
|
||||
Com_Error(ERR_FATAL, "Failed to load renderer");
|
||||
}
|
||||
|
||||
GetRefAPI = (GetRefAPI_t)Sys_LoadFunction(rendererLib, "GetRefAPI");
|
||||
if(!GetRefAPI)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "Can't load symbol GetRefAPI: '%s'", Sys_LibraryError());
|
||||
}
|
||||
#endif
|
||||
|
||||
ri.Cmd_AddCommand = Cmd_AddCommand;
|
||||
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
|
||||
ri.Cmd_Argc = Cmd_Argc;
|
||||
@@ -3027,8 +3168,10 @@ void CL_InitRef( void ) {
|
||||
ri.CM_DrawDebugSurface = CM_DrawDebugSurface;
|
||||
|
||||
ri.FS_OpenFile = FS_FOpenFileRead;
|
||||
ri.FS_OpenFileWrite = FS_FOpenFileWrite;
|
||||
ri.FS_CloseFile = FS_FCloseFile;
|
||||
ri.FS_Read = FS_Read;
|
||||
ri.FS_Write = FS_Write;
|
||||
ri.FS_Seek = FS_Seek;
|
||||
ri.FS_ReadFile = FS_ReadFile;
|
||||
ri.FS_ReadFileEx = FS_ReadFileEx;
|
||||
@@ -3038,8 +3181,10 @@ void CL_InitRef( void ) {
|
||||
ri.FS_ListFiles = CL_RefFS_ListFiles;
|
||||
ri.FS_FileIsInPAK = FS_FileIsInPAK;
|
||||
ri.FS_FileExists = FS_FileExists;
|
||||
ri.FS_CanonicalFilename = FS_CanonicalFilename;
|
||||
ri.Cvar_Get = Cvar_Get;
|
||||
ri.Cvar_Set = Cvar_Set;
|
||||
ri.Cvar_SetValue = Cvar_SetValue;
|
||||
ri.Cvar_SetDefault = Cvar_SetDefault;
|
||||
|
||||
ri.CM_EntityString = CM_EntityString;
|
||||
@@ -3088,40 +3233,30 @@ void CL_InitRef( void ) {
|
||||
ri.Sys_GLimpInit = Sys_GLimpInit;
|
||||
ri.Sys_LowPhysicalMemory = Sys_LowPhysicalMemory;
|
||||
|
||||
#ifdef USE_RENDERER_DLL
|
||||
// su44: load renderer dll
|
||||
cl_renderer = Cvar_Get("cl_renderer", "glom", CVAR_ARCHIVE);
|
||||
Q_snprintf(dllName, sizeof(dllName), "renderer_%s" ARCH_STRING DLL_EXT, cl_renderer->string);
|
||||
Com_Printf("Loading \"%s\"...", dllName);
|
||||
if((rendererLib = Sys_LoadLibrary(dllName)) == 0) {
|
||||
#ifdef _WIN32
|
||||
Com_Error(ERR_FATAL, "failed:\n\"%s\"\n", Sys_LibraryError());
|
||||
#else
|
||||
char fn[1024];
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
ri.UI_LoadResource = UI_LoadResource;
|
||||
ri.CM_PointLeafnum = CM_PointLeafnum;
|
||||
ri.CM_LeafCluster = CM_LeafCluster;
|
||||
|
||||
Q_strncpyz(fn, Sys_Cwd(), sizeof(fn));
|
||||
strncat(fn, "/", sizeof(fn) - strlen(fn) - 1);
|
||||
strncat(fn, dllName, sizeof(fn) - strlen(fn) - 1);
|
||||
ri.TIKI_CalcLodConsts = TIKI_CalcLodConsts;
|
||||
ri.TIKI_CalculateBounds = TIKI_CalculateBounds;
|
||||
ri.TIKI_FindTiki = TIKI_FindTiki;
|
||||
ri.TIKI_RegisterTikiFlags = TIKI_RegisterTikiFlags;
|
||||
ri.TIKI_GetSkeletor = TIKI_GetSkeletor;
|
||||
ri.TIKI_GetSkel = TIKI_GetSkel;
|
||||
ri.TIKI_GetSkelAnimFrame = TIKI_GetSkelAnimFrame;
|
||||
ri.TIKI_GlobalRadius = TIKI_GlobalRadius;
|
||||
ri.TIKI_FindSkelByHeader = TIKI_FindSkelByHeader;
|
||||
ri.TIKI_GetNumChannels = CL_RefTIKI_GetNumChannels;
|
||||
ri.TIKI_GetLocalChannel = CL_RefTIKI_GetLocalChannel;
|
||||
ri.TIKI_GetLocalFromGlobal = CL_RefTIKI_GetLocalFromGlobal;
|
||||
|
||||
Com_Printf("Loading \"%s\"...", fn);
|
||||
if((rendererLib = Sys_LoadLibrary(fn)) == 0)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "failed:\n\"%s\"", Sys_LibraryError());
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
ri.SKEL_GetBoneParent = CL_RefSKEL_GetBoneParent;
|
||||
ri.SKEL_GetMorphWeightFrame = CL_RefSKEL_GetMorphWeightFrame;
|
||||
|
||||
Com_Printf("done\n");
|
||||
|
||||
DGetRefAPI = Sys_LoadFunction(rendererLib, "GetRefAPI");
|
||||
if(!DGetRefAPI)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "Can't load symbol GetRefAPI: '%s'", Sys_LibraryError());
|
||||
}
|
||||
ret = DGetRefAPI( REF_API_VERSION, &ri );
|
||||
#else
|
||||
ret = GetRefAPI( REF_API_VERSION, &ri );
|
||||
#endif
|
||||
|
||||
#if defined __USEA3D && defined __A3D_GEOM
|
||||
hA3Dg_ExportRenderGeom (ret);
|
||||
@@ -3137,6 +3272,8 @@ void CL_InitRef( void ) {
|
||||
|
||||
// unpause so the cgame definately gets a snapshot and renders a frame
|
||||
Cvar_Set( "cl_paused", "0" );
|
||||
|
||||
cls.refSequence++;
|
||||
}
|
||||
|
||||
|
||||
@@ -3488,14 +3625,6 @@ void CL_Init( void ) {
|
||||
Cvar_Get ("dm_playermodel", "american_army", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("dm_playergermanmodel", "german_wehrmacht_soldier", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
|
||||
Cvar_Get ("cg_predictItems", "1", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
|
||||
|
||||
// cgame might not be initialized before menu is used
|
||||
Cvar_Get ("cg_viewsize", "100", CVAR_ARCHIVE );
|
||||
|
||||
Cvar_Get ("cg_running", "0", CVAR_ROM );
|
||||
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
@@ -3925,7 +4054,7 @@ CL_ServerStatusResponse
|
||||
void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
|
||||
const char *s;
|
||||
char info[MAX_INFO_STRING];
|
||||
int i, l, score, ping;
|
||||
int i, l, ping;
|
||||
int len;
|
||||
serverStatus_t *serverStatus;
|
||||
|
||||
@@ -3979,7 +4108,7 @@ void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
|
||||
|
||||
if (serverStatus->print) {
|
||||
Com_Printf("\nPlayers:\n");
|
||||
Com_Printf("num: score: ping: name:\n");
|
||||
Com_Printf("num: ping: name:\n");
|
||||
}
|
||||
for (i = 0, s = MSG_ReadStringLine( msg ); *s; s = MSG_ReadStringLine( msg ), i++) {
|
||||
|
||||
@@ -3987,16 +4116,14 @@ void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
|
||||
Com_sprintf(&serverStatus->string[len], sizeof(serverStatus->string)-len, "\\%s", s);
|
||||
|
||||
if (serverStatus->print) {
|
||||
score = ping = 0;
|
||||
sscanf(s, "%d %d", &score, &ping);
|
||||
ping = 0;
|
||||
sscanf(s, "%d", &ping);
|
||||
s = strchr(s, ' ');
|
||||
if (s)
|
||||
s = strchr(s+1, ' ');
|
||||
if (s)
|
||||
s++;
|
||||
else
|
||||
s = "unknown";
|
||||
Com_Printf("%-2d %-3d %-3d %s\n", i, score, ping, s );
|
||||
Com_Printf("%-2d %-3d %s\n", i, ping, s );
|
||||
}
|
||||
}
|
||||
len = strlen(serverStatus->string);
|
||||
|
||||
@@ -568,6 +568,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
csNum = CPT_NormalizeConfigstring(i);
|
||||
if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) {
|
||||
Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
|
||||
return;
|
||||
}
|
||||
s = MSG_ReadScrambledBigString(msg);
|
||||
len = strlen(s);
|
||||
@@ -588,8 +589,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
//Com_Memset (&nullstate, 0, sizeof(nullstate));
|
||||
MSG_GetNullEntityState(&nullstate);
|
||||
es = &cl.entityBaselines[ newnum ];
|
||||
// FIXME: frametime
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, 0.0);
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, cls.serverFrameTime);
|
||||
} else {
|
||||
Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte %i", cmd );
|
||||
}
|
||||
@@ -606,16 +606,25 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
// stop recording now so the demo won't have an unnecessary level load at the end.
|
||||
if(cl_autoRecordDemo->integer && clc.demorecording)
|
||||
CL_StopRecord_f();
|
||||
|
||||
// reinitialize the filesystem if the game directory has changed
|
||||
FS_ConditionalRestart( clc.checksumFeed, qfalse );
|
||||
|
||||
if (clc.state == CA_CONNECTED && !Cvar_Get("sv_paks", "", 0)->string[0]) {
|
||||
// Added in 2.30
|
||||
FS_Restart(clc.checksumFeed);
|
||||
} else {
|
||||
// reinitialize the filesystem if the game directory has changed
|
||||
FS_ConditionalRestart(clc.checksumFeed, qfalse);
|
||||
}
|
||||
|
||||
clc.state = CA_LOADING;
|
||||
if (!com_sv_running->integer)
|
||||
{
|
||||
const char *info = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SERVERINFO];
|
||||
UI_ClearState();
|
||||
UI_BeginLoad(Info_ValueForKey(info, "mapname"));
|
||||
const char *mapname = Info_ValueForKey(info, "mapname");
|
||||
// Added in 2.0
|
||||
Cvar_Set("mapname", mapname);
|
||||
|
||||
UI_ClearState();
|
||||
UI_BeginLoad(mapname);
|
||||
}
|
||||
|
||||
// This used to call CL_StartHunkUsers, but now we enter the download state before loading the
|
||||
|
||||
+94
-32
@@ -143,6 +143,9 @@ static unsigned int totalLoadTime;
|
||||
static unsigned int currentLoadTime;
|
||||
unsigned char UIListCtrlItem[8];
|
||||
|
||||
static const float maxWidthRes = 1920;
|
||||
static const float maxHeightRes = 1080;
|
||||
|
||||
inventory_t client_inv;
|
||||
bind_t client_bind;
|
||||
static str scoreboard_menuname;
|
||||
@@ -212,15 +215,15 @@ static UIRect2D getDefaultConsoleRectangle(void)
|
||||
f[i] = floor(f[i]);
|
||||
}
|
||||
|
||||
rect.pos.x = f[0] - cls.glconfig.vidWidth;
|
||||
rect.pos.y = f[1] - cls.glconfig.vidHeight;
|
||||
rect.pos.x = f[0] - uid.vidWidth;
|
||||
rect.pos.y = f[1] - uid.vidHeight;
|
||||
rect.size.width = f[2] + 50.0;
|
||||
rect.size.height = f[3] + 50.0;
|
||||
} else {
|
||||
rect.pos.x = 25.0;
|
||||
rect.pos.y = 25.0;
|
||||
rect.size.width = (cls.glconfig.vidWidth - 50);
|
||||
rect.size.height = (cls.glconfig.vidHeight / 2);
|
||||
rect.size.width = (uid.vidWidth - 50);
|
||||
rect.size.height = (uid.vidHeight / 2);
|
||||
}
|
||||
|
||||
return rect;
|
||||
@@ -967,15 +970,15 @@ static UIRect2D getDefaultDMConsoleRectangle(void)
|
||||
f[i] = floor(f[i]);
|
||||
}
|
||||
|
||||
rect.pos.x = f[0] - cls.glconfig.vidWidth;
|
||||
rect.pos.y = f[1] - cls.glconfig.vidHeight;
|
||||
rect.pos.x = f[0] - uid.vidWidth;
|
||||
rect.pos.y = f[1] - uid.vidHeight;
|
||||
rect.size.width = f[2] + 50.0;
|
||||
rect.size.height = f[3] + 50.0;
|
||||
} else {
|
||||
rect.pos.x = 0;
|
||||
rect.pos.y = cls.glconfig.vidHeight * 0.58;
|
||||
rect.size.width = cls.glconfig.vidWidth;
|
||||
rect.size.height = cls.glconfig.vidHeight * 0.415;
|
||||
rect.pos.y = uid.vidHeight * 0.58;
|
||||
rect.size.width = uid.vidWidth;
|
||||
rect.size.height = uid.vidHeight * 0.415;
|
||||
}
|
||||
|
||||
return rect;
|
||||
@@ -997,19 +1000,19 @@ static UIRect2D getQuickMessageDMConsoleRectangle(void)
|
||||
f[i] = floor(f[i]);
|
||||
}
|
||||
|
||||
rect.pos.x = f[0] - cls.glconfig.vidWidth;
|
||||
rect.pos.y = f[1] - cls.glconfig.vidHeight;
|
||||
rect.pos.x = f[0] - uid.vidWidth;
|
||||
rect.pos.y = f[1] - uid.vidHeight;
|
||||
rect.size.width = f[2] + 50.0;
|
||||
rect.size.height = f[3] + 50.0;
|
||||
} else {
|
||||
rect.pos.x = 0;
|
||||
rect.pos.y = cls.glconfig.vidHeight * 0.66;
|
||||
rect.size.width = cls.glconfig.vidWidth;
|
||||
rect.pos.y = uid.vidHeight * 0.66;
|
||||
rect.size.width = uid.vidWidth;
|
||||
// Fixed in 2.0
|
||||
// Was 38.0 in 1.11 and below
|
||||
// This prevents characters to be seen from the DM console
|
||||
// in the quick message console
|
||||
rect.size.height = 36.0;
|
||||
rect.size.height = 36.0 * uid.scaleRes[1];
|
||||
}
|
||||
|
||||
return rect;
|
||||
@@ -1128,6 +1131,20 @@ static void DMConsoleCommandHandler(const char *txt)
|
||||
CL_AddReliableCommand(szStringOut, qfalse);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
getScreenWidth
|
||||
====================
|
||||
*/
|
||||
static float getScreenWidth()
|
||||
{
|
||||
if (uid.bHighResScaling) {
|
||||
return maxWidthRes;
|
||||
} else {
|
||||
return uid.vidWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
getNewConsole
|
||||
@@ -1189,14 +1206,14 @@ getDefaultGMBoxRectangle
|
||||
static UIRect2D getDefaultGMBoxRectangle(void)
|
||||
{
|
||||
UIRect2D dmRect = getDefaultDMBoxRectangle();
|
||||
float height = cls.glconfig.vidHeight * ui_compass_scale->value * 0.25f;
|
||||
float height = uid.vidHeight * ui_compass_scale->value * 0.25f;
|
||||
float y = dmRect.size.height + dmRect.pos.y;
|
||||
|
||||
if (height < y) {
|
||||
height = y;
|
||||
}
|
||||
|
||||
return UIRect2D(20.0f, height, cls.glconfig.vidWidth - 20, 128.0f);
|
||||
return UIRect2D(20.0f, height, (getScreenWidth() - 20) * uid.scaleRes[0], 128.0f * uid.scaleRes[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1206,9 +1223,12 @@ getDefaultDMBoxRectangle
|
||||
*/
|
||||
static UIRect2D getDefaultDMBoxRectangle(void)
|
||||
{
|
||||
float width = cls.glconfig.vidWidth * ui_compass_scale->value * 0.2f;
|
||||
float width;
|
||||
float screenWidth = getScreenWidth();
|
||||
|
||||
width = screenWidth * uid.scaleRes[0] * ui_compass_scale->value * 0.2f;
|
||||
|
||||
return UIRect2D(width, 0, cls.glconfig.vidWidth - (width + 192.0f), 120.0f);
|
||||
return UIRect2D(width, 0, (screenWidth - (width + 192.0f)) * uid.scaleRes[0], 120.0f * uid.scaleRes[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1221,6 +1241,21 @@ float UI_GetObjectivesTop(void)
|
||||
return getDefaultGMBoxRectangle().pos.y;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_GetObjectivesTop
|
||||
====================
|
||||
*/
|
||||
void UI_GetHighResolutionScale(vec2_t scale)
|
||||
{
|
||||
if (uid.bHighResScaling) {
|
||||
scale[0] = uid.scaleRes[0];
|
||||
scale[1] = uid.scaleRes[1];
|
||||
} else {
|
||||
scale[0] = scale[1] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_ShowHudList
|
||||
@@ -1681,11 +1716,11 @@ UI_ClearBackground
|
||||
void UI_ClearBackground(void)
|
||||
{
|
||||
re.Set2DWindow(
|
||||
0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, -1, 1
|
||||
0, 0, uid.vidWidth, uid.vidHeight, 0, uid.vidWidth, uid.vidHeight, 0, -1, 1
|
||||
);
|
||||
re.Scissor(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight);
|
||||
re.Scissor(0, 0, uid.vidWidth, uid.vidHeight);
|
||||
re.SetColor(g_color_table[0]);
|
||||
re.DrawBox(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight);
|
||||
re.DrawBox(0, 0, uid.vidWidth, uid.vidHeight);
|
||||
re.SetColor(NULL);
|
||||
}
|
||||
|
||||
@@ -3098,7 +3133,7 @@ void UI_MapList_f(void)
|
||||
MapRunnerClass *map = new MapRunnerClass;
|
||||
map->Setup("maps", mappath, ".bsp", "_sml");
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3138,7 +3173,7 @@ void UI_DMMapSelect_f(void)
|
||||
MpMapPickerClass *map = new MpMapPickerClass;
|
||||
map->Setup(basepath, mappath, gametype);
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3322,7 +3357,7 @@ void UI_PlayerModel_f(void)
|
||||
PlayerModelPickerClass *picker = new PlayerModelPickerClass;
|
||||
picker->Setup("models/player", modelpath, bGermanModel);
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3712,6 +3747,7 @@ void CL_FillUIImports(void)
|
||||
uii.Rend_Scissor = re.Scissor;
|
||||
uii.Rend_Set2D = re.Set2DWindow;
|
||||
uii.Rend_SetColor = re.SetColor;
|
||||
uii.Rend_ImageExists = re.ImageExists;
|
||||
|
||||
uii.Cmd_Stuff = Cbuf_AddText;
|
||||
uii.Cvar_GetString = CvarGetForUI;
|
||||
@@ -3750,6 +3786,9 @@ void CL_FillUIImports(void)
|
||||
|
||||
uii.GetConfigstring = CL_ConfigString;
|
||||
uii.UI_CloseDMConsole = UI_CloseDMConsole;
|
||||
|
||||
uii.GetRefSequence = CL_GetRefSequence;
|
||||
uii.IsRendererLoaded = CL_IsRendererLoaded;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3806,7 +3845,7 @@ void UI_CreateDialog(
|
||||
{
|
||||
UIDialog *dlg = new UIDialog;
|
||||
UIRect2D rect =
|
||||
UIRect2D((cls.glconfig.vidWidth - width) >> 1, (cls.glconfig.vidHeight - height) >> 1, width, height);
|
||||
UIRect2D((uid.vidWidth - width) / 2, (uid.vidHeight - height) / 2, width, height);
|
||||
UColor bgColor = UWindowColor;
|
||||
|
||||
dlg->Create(NULL, rect, title, bgColor, UHudColor);
|
||||
@@ -3836,12 +3875,28 @@ void UI_ResolutionChange(void)
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
} else {
|
||||
// Older version doesn't have an adjustable compass, so assume 0.5 by default
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.5", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.55", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
}
|
||||
|
||||
CL_FillUIImports();
|
||||
CL_FillUIDef();
|
||||
|
||||
// Added in OPM
|
||||
// Scaling for high resolutions
|
||||
if (uid.vidWidth > maxWidthRes && uid.vidHeight > maxHeightRes) {
|
||||
const float vidRatio = (float)uid.vidWidth / (float)uid.vidHeight;
|
||||
|
||||
uid.scaleRes[0] = (float)uid.vidWidth / (maxHeightRes * vidRatio);
|
||||
uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
|
||||
//uid.scaleRes[0] = (float)uid.vidWidth / maxWidthRes;
|
||||
//uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
|
||||
uid.bHighResScaling = qtrue;
|
||||
} else {
|
||||
uid.scaleRes[0] = 1;
|
||||
uid.scaleRes[1] = 1;
|
||||
uid.bHighResScaling = qfalse;
|
||||
}
|
||||
|
||||
if (!uie.ResolutionChange) {
|
||||
return;
|
||||
}
|
||||
@@ -3876,7 +3931,7 @@ void UI_ResolutionChange(void)
|
||||
menuManager.RealignMenus();
|
||||
|
||||
if (view3d) {
|
||||
frame = UIRect2D(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight);
|
||||
frame = UIRect2D(0, 0, uid.vidWidth, uid.vidHeight);
|
||||
view3d->setFrame(frame);
|
||||
}
|
||||
|
||||
@@ -4409,7 +4464,7 @@ void ScoreboardListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
|
||||
{
|
||||
DrawBox(drawRect, backColor, 1.0);
|
||||
pFont->setColor(textColor);
|
||||
pFont->Print(drawRect.pos.x + 1, drawRect.pos.y, Sys_LV_CL_ConvertString(getListItemString(iColumn)), -1, qfalse);
|
||||
pFont->Print((drawRect.pos.x + 1) / uid.scaleRes[0], drawRect.pos.y / uid.scaleRes[1], Sys_LV_CL_ConvertString(getListItemString(iColumn)), -1, uid.scaleRes);
|
||||
|
||||
if (bTitleItem) {
|
||||
UIRect2D lineRect;
|
||||
@@ -4462,7 +4517,7 @@ void UI_CreateScoreboard(void)
|
||||
scoreboard_h = h;
|
||||
|
||||
SCR_AdjustFrom640(&x, &y, &w, &h);
|
||||
fColumnScale = cls.glconfig.vidWidth / 640.0;
|
||||
fColumnScale = uid.vidWidth / 640.0;
|
||||
cge->CG_GetScoreBoardColor(&fR, &fG, &fB, &fA);
|
||||
cge->CG_GetScoreBoardFontColor(&fFontR, &fFontG, &fFontB, &fFontA);
|
||||
|
||||
@@ -5308,7 +5363,7 @@ void CL_InitializeUI(void)
|
||||
// Create the 3D view
|
||||
view3d = new View3D;
|
||||
view3d->setAlwaysOnBottom(true);
|
||||
view3d->InitFrame(NULL, 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, -1, "facfont-20");
|
||||
view3d->InitFrame(NULL, 0, 0, uid.vidWidth, uid.vidHeight, -1, "facfont-20");
|
||||
view3d->setName("view3d");
|
||||
view3d->InitSubtitle();
|
||||
|
||||
@@ -5504,7 +5559,7 @@ qboolean UI_IsResourceLoaded(const char *name)
|
||||
case 107:
|
||||
return S_IsSoundRegistered(name + 1);
|
||||
case 110:
|
||||
return R_ImageExists(name + 1);
|
||||
return uii.Rend_ImageExists(name + 1);
|
||||
default:
|
||||
return qfalse;
|
||||
}
|
||||
@@ -5765,8 +5820,15 @@ void UI_BeginLoad(const char *pszMapName)
|
||||
|
||||
loadName = "maps/";
|
||||
loadName += pszMapName;
|
||||
mapfile = loadName;
|
||||
loadName += ".min";
|
||||
mapfile = loadName + ".bsp";
|
||||
|
||||
if (CL_UseLargeLightmap(pszMapName)) {
|
||||
mapfile += ".bsp";
|
||||
} else {
|
||||
// Added in 2.0
|
||||
mapfile += "_sml.bsp";
|
||||
}
|
||||
|
||||
if (UI_ArchiveLoadMapinfo(mapfile)) {
|
||||
cls.loading = SS_LOADING2;
|
||||
|
||||
@@ -57,6 +57,7 @@ void UI_ClearState(void);
|
||||
void CL_BeginRegistration(void);
|
||||
void CL_EndRegistration(void);
|
||||
float UI_GetObjectivesTop(void);
|
||||
void UI_GetHighResolutionScale(vec2_t scale);
|
||||
|
||||
//
|
||||
// menu
|
||||
|
||||
+280
-310
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -40,127 +40,116 @@ Event EV_DMBox_Decay
|
||||
"Event to make the dmbox console line decay"
|
||||
);
|
||||
|
||||
static float s_dmboxWidth = 384.0;
|
||||
static float s_dmboxWidth = 384.0;
|
||||
static float s_dmboxOffsetX = 3.0f;
|
||||
static float s_dmboxOffsetY = 8.0f;
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UIDMBox, NULL )
|
||||
{
|
||||
{ &W_SizeChanged, &UIDMBox::OnSizeChanged },
|
||||
{ &EV_DMBox_Goin, &UIDMBox::MoveInEvent },
|
||||
{ &EV_DMBox_Decay, &UIDMBox::DecayEvent },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, UIDMBox, NULL) {
|
||||
{&W_SizeChanged, &UIDMBox::OnSizeChanged},
|
||||
{&EV_DMBox_Goin, &UIDMBox::MoveInEvent },
|
||||
{&EV_DMBox_Decay, &UIDMBox::DecayEvent },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIDMBox::UIDMBox()
|
||||
{
|
||||
m_numitems = 0;
|
||||
m_reallyshown = true;
|
||||
m_fontbold = NULL;
|
||||
m_boxstate = boxstate_t::box_out;
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
m_numitems = 0;
|
||||
m_reallyshown = true;
|
||||
m_fontbold = NULL;
|
||||
m_boxstate = boxstate_t::box_out;
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIDMBox::VerifyBoxOut( void )
|
||||
void UIDMBox::VerifyBoxOut(void)
|
||||
{
|
||||
PostMoveinEvent();
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out)
|
||||
{
|
||||
ChangeBoxState(boxstate_t::box_moving_out);
|
||||
}
|
||||
PostMoveinEvent();
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) {
|
||||
ChangeBoxState(boxstate_t::box_moving_out);
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::ChangeBoxState( boxstate_t state )
|
||||
void UIDMBox::ChangeBoxState(boxstate_t state)
|
||||
{
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
|
||||
if (state == box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
if (state == box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::HandleBoxMoving( void )
|
||||
void UIDMBox::HandleBoxMoving(void)
|
||||
{
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
|
||||
return;
|
||||
}
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
if (m_boxstate == boxstate_t::box_moving_out)
|
||||
{
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta + m_frame.pos.y;
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
if (m_boxstate == boxstate_t::box_moving_out) {
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta + m_frame.pos.y;
|
||||
|
||||
if (newRect.pos.y <= 0.0)
|
||||
{
|
||||
newRect.pos.y = 0.0;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
}
|
||||
else if (m_boxstate == boxstate_t::box_moving_in)
|
||||
{
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta - m_frame.pos.y;
|
||||
if (newRect.pos.y <= 0.0) {
|
||||
newRect.pos.y = 0.0;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
} else if (m_boxstate == boxstate_t::box_moving_in) {
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta - m_frame.pos.y;
|
||||
|
||||
if (newRect.pos.y <= -newRect.size.height)
|
||||
{
|
||||
newRect.pos.y = -newRect.size.height;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
}
|
||||
else {
|
||||
newRect = m_frame;
|
||||
}
|
||||
if (newRect.pos.y <= -newRect.size.height) {
|
||||
newRect.pos.y = -newRect.size.height;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
} else {
|
||||
newRect = m_frame;
|
||||
}
|
||||
|
||||
setFrame(newRect);
|
||||
setFrame(newRect);
|
||||
}
|
||||
|
||||
void UIDMBox::PostMoveinEvent( void )
|
||||
void UIDMBox::PostMoveinEvent(void)
|
||||
{
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EventPending(EV_DMBox_Goin)) {
|
||||
PostEvent(EV_DMBox_Goin, 10.0);
|
||||
}
|
||||
else {
|
||||
PostponeEvent(EV_DMBox_Goin, 10.0);
|
||||
}
|
||||
if (!EventPending(EV_DMBox_Goin)) {
|
||||
PostEvent(EV_DMBox_Goin, 10.0);
|
||||
} else {
|
||||
PostponeEvent(EV_DMBox_Goin, 10.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::PostDecayEvent( void )
|
||||
void UIDMBox::PostDecayEvent(void)
|
||||
{
|
||||
if (!EventPending(EV_DMBox_Decay))
|
||||
{
|
||||
float fDelayTime;
|
||||
int iNumLines;
|
||||
int i;
|
||||
const char* pszString = m_items[0].string.c_str();
|
||||
if (!EventPending(EV_DMBox_Decay)) {
|
||||
float fDelayTime;
|
||||
int iNumLines;
|
||||
int i;
|
||||
const char *pszString = m_items[0].string.c_str();
|
||||
|
||||
//
|
||||
// Calculate the number of lines
|
||||
//
|
||||
iNumLines = 1;
|
||||
for (i = 0; pszString[i]; i++)
|
||||
{
|
||||
if (pszString[i] == '\n') {
|
||||
iNumLines++;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Calculate the number of lines
|
||||
//
|
||||
iNumLines = 1;
|
||||
for (i = 0; pszString[i]; i++) {
|
||||
if (pszString[i] == '\n') {
|
||||
iNumLines++;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_items[0].flags & DMBOX_ITEM_FLAG_BOLD) {
|
||||
fDelayTime = iNumLines * 8.0;
|
||||
@@ -168,291 +157,272 @@ void UIDMBox::PostDecayEvent( void )
|
||||
//
|
||||
// Bold as twice more decay
|
||||
//
|
||||
else if (m_items[0].flags & DMBOX_ITEM_FLAG_DEATH) {
|
||||
fDelayTime = iNumLines * 6.0;
|
||||
}
|
||||
else {
|
||||
fDelayTime = iNumLines * 5.0;
|
||||
}
|
||||
else if (m_items[0].flags & DMBOX_ITEM_FLAG_DEATH) {
|
||||
fDelayTime = iNumLines * 6.0;
|
||||
} else {
|
||||
fDelayTime = iNumLines * 5.0;
|
||||
}
|
||||
|
||||
m_iBeginDecay = cls.realtime;
|
||||
m_iEndDecay = (int)(fDelayTime * 1000.0);
|
||||
m_iBeginDecay = cls.realtime;
|
||||
m_iEndDecay = (int)(fDelayTime * 1000.0);
|
||||
|
||||
PostEvent(EV_DMBox_Decay, fDelayTime);
|
||||
}
|
||||
PostEvent(EV_DMBox_Decay, fDelayTime);
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::setShowState( void )
|
||||
void UIDMBox::setShowState(void)
|
||||
{
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::RemoveTopItem( void )
|
||||
void UIDMBox::RemoveTopItem(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (m_numitems > 0) {
|
||||
for (i = 0; i < m_numitems - 1; i++) {
|
||||
m_items[i] = m_items[i + 1];
|
||||
}
|
||||
if (m_numitems > 0) {
|
||||
for (i = 0; i < m_numitems - 1; i++) {
|
||||
m_items[i] = m_items[i + 1];
|
||||
}
|
||||
|
||||
m_numitems--;
|
||||
}
|
||||
m_numitems--;
|
||||
}
|
||||
}
|
||||
|
||||
str UIDMBox::CalculateBreaks( UIFont *font, str text, float max_width )
|
||||
str UIDMBox::CalculateBreaks(UIFont *font, str text, float max_width)
|
||||
{
|
||||
str newText, sTmp;
|
||||
int i;
|
||||
float fX;
|
||||
float fwX, fsX;
|
||||
str newText;
|
||||
float fX;
|
||||
float fwX;
|
||||
const char *current;
|
||||
int count;
|
||||
|
||||
Cmd_TokenizeString(text.c_str());
|
||||
if (Cmd_Argc())
|
||||
{
|
||||
fX = 0.0;
|
||||
fsX = font->getCharWidth(' ');
|
||||
current = text;
|
||||
fX = 0.0;
|
||||
|
||||
for (i = 0; i < Cmd_Argc(); i++)
|
||||
{
|
||||
sTmp = Cmd_Argv(i);
|
||||
for (count = font->DBCSGetWordBlockCount(current, -1); count;
|
||||
current += count, count = font->DBCSGetWordBlockCount(current, -1)) {
|
||||
fwX = font->getWidth(current, count);
|
||||
|
||||
fwX = font->getWidth(sTmp.c_str(), -1);
|
||||
if (fwX + i <= max_width)
|
||||
{
|
||||
if (fwX + i + fX <= max_width)
|
||||
{
|
||||
newText += sTmp + " ";
|
||||
} else {
|
||||
newText += "\n" + sTmp + " ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sTmp += "\n";
|
||||
fX = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newText = "";
|
||||
}
|
||||
if (fX + fwX > max_width) {
|
||||
newText += "\n" + str(current, 0, count);
|
||||
fX = 0;
|
||||
} else {
|
||||
newText += str(current, 0, count);
|
||||
}
|
||||
|
||||
return newText;
|
||||
fX += fwX;
|
||||
}
|
||||
|
||||
return newText;
|
||||
}
|
||||
|
||||
float UIDMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
float UIDMBox::PrintWrap(UIFont *font, float x, float y, str text)
|
||||
{
|
||||
const char* p1, * p2;
|
||||
size_t n, l;
|
||||
float fY;
|
||||
const char *p1, *p2;
|
||||
size_t n, l;
|
||||
float fY;
|
||||
|
||||
fY = y;
|
||||
p1 = text.c_str();
|
||||
l = text.length();
|
||||
fY = y;
|
||||
p1 = text.c_str();
|
||||
l = text.length();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
p2 = strchr(p1, '\n');
|
||||
if (!p2) {
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
p2 = strchr(p1, '\n');
|
||||
if (!p2) {
|
||||
break;
|
||||
}
|
||||
|
||||
n = p2 - p1;
|
||||
if (n >= l) {
|
||||
break;
|
||||
}
|
||||
n = p2 - p1;
|
||||
if (n >= l) {
|
||||
break;
|
||||
}
|
||||
|
||||
font->Print(x, fY, p1, p2 - p1, qfalse);
|
||||
p1 = p2 + 1;
|
||||
l -= n;
|
||||
fY += font->getHeight(qfalse);
|
||||
}
|
||||
font->Print(x, fY, p1, p2 - p1, getHighResScale());
|
||||
p1 = p2 + 1;
|
||||
l -= n;
|
||||
fY += font->getHeight();
|
||||
}
|
||||
|
||||
font->Print(x, fY, p1, l, qfalse);
|
||||
if (*p1) {
|
||||
font->Print(x, fY, p1, l, getHighResScale());
|
||||
fY += font->getHeight();
|
||||
}
|
||||
|
||||
return font->getHeight(qfalse) + (fY - y);
|
||||
return fY - y;
|
||||
}
|
||||
|
||||
float UIDMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
float UIDMBox::DrawItem(item_t *in, float x, float y, float alpha)
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
return PrintWrap(in->font, x, y, in->string);
|
||||
return PrintWrap(in->font, x, y, in->string);
|
||||
}
|
||||
|
||||
void UIDMBox::Print( const char *text )
|
||||
void UIDMBox::Print(const char *text)
|
||||
{
|
||||
const char* text1 = text;
|
||||
const char *text1 = text;
|
||||
|
||||
if (m_numitems > 5)
|
||||
{
|
||||
//
|
||||
// Overwrite an item
|
||||
//
|
||||
RemoveTopItem();
|
||||
}
|
||||
if (m_numitems > 5) {
|
||||
//
|
||||
// Overwrite an item
|
||||
//
|
||||
RemoveTopItem();
|
||||
}
|
||||
|
||||
m_items[m_numitems].flags = 0;
|
||||
m_items[m_numitems].flags = 0;
|
||||
|
||||
if (*text == MESSAGE_CHAT_WHITE)
|
||||
{
|
||||
m_items[m_numitems].color = UGrey;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_BOLD;
|
||||
if (*text == MESSAGE_CHAT_WHITE) {
|
||||
m_items[m_numitems].color = UGrey;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_BOLD;
|
||||
|
||||
text1 = text + 1;
|
||||
}
|
||||
else if (*text == MESSAGE_CHAT_RED)
|
||||
{
|
||||
m_items[m_numitems].color = ULightRed;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
|
||||
text1 = text + 1;
|
||||
} else if (*text == MESSAGE_CHAT_RED) {
|
||||
m_items[m_numitems].color = ULightRed;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
|
||||
|
||||
text1 = text + 1;
|
||||
}
|
||||
else if (*text == MESSAGE_CHAT_GREEN)
|
||||
{
|
||||
if (com_target_game->integer >= TG_MOHTA) {
|
||||
m_items[m_numitems].color = ULightGreen;
|
||||
} else {
|
||||
m_items[m_numitems].color = UGreen;
|
||||
}
|
||||
text1 = text + 1;
|
||||
} else if (*text == MESSAGE_CHAT_GREEN) {
|
||||
if (com_target_game->integer >= TG_MOHTA) {
|
||||
m_items[m_numitems].color = ULightGreen;
|
||||
} else {
|
||||
m_items[m_numitems].color = UGreen;
|
||||
}
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
|
||||
|
||||
text1 = text + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_items[m_numitems].color = m_foreground_color;
|
||||
m_items[m_numitems].font = m_font;
|
||||
}
|
||||
text1 = text + 1;
|
||||
} else {
|
||||
m_items[m_numitems].color = m_foreground_color;
|
||||
m_items[m_numitems].font = m_font;
|
||||
}
|
||||
|
||||
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_dmboxWidth);
|
||||
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_dmboxWidth);
|
||||
|
||||
m_numitems++;
|
||||
VerifyBoxOut();
|
||||
PostDecayEvent();
|
||||
m_numitems++;
|
||||
VerifyBoxOut();
|
||||
PostDecayEvent();
|
||||
}
|
||||
|
||||
void UIDMBox::OnSizeChanged( Event *ev )
|
||||
void UIDMBox::OnSizeChanged(Event *ev)
|
||||
{
|
||||
s_dmboxWidth = m_frame.size.width;
|
||||
s_dmboxWidth = m_frame.size.width;
|
||||
}
|
||||
|
||||
void UIDMBox::Create( const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha )
|
||||
void UIDMBox::Create(const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha)
|
||||
{
|
||||
InitFrame(NULL, rect, 0, "facfont-20");
|
||||
InitFrame(NULL, rect, 0, "facfont-20");
|
||||
|
||||
if (!m_fontbold) {
|
||||
m_fontbold = new UIFont("facfont-20");
|
||||
}
|
||||
if (!m_fontbold) {
|
||||
m_fontbold = new UIFont("facfont-20");
|
||||
}
|
||||
|
||||
m_fontbold->setColor(URed);
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
m_fontbold->setColor(URed);
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
|
||||
m_movespeed = rect.size.height * 3.0;
|
||||
m_movespeed = rect.size.height * 3.0;
|
||||
|
||||
setShowState();
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void UIDMBox::MoveInEvent( Event *ev )
|
||||
void UIDMBox::MoveInEvent(Event *ev) {}
|
||||
|
||||
void UIDMBox::DecayEvent(Event *ev)
|
||||
{
|
||||
RemoveTopItem();
|
||||
if (m_numitems) {
|
||||
PostDecayEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::DecayEvent( Event *ev )
|
||||
void UIDMBox::Draw(void)
|
||||
{
|
||||
RemoveTopItem();
|
||||
if (m_numitems) {
|
||||
PostDecayEvent();
|
||||
}
|
||||
float fsY;
|
||||
int i;
|
||||
float alpha;
|
||||
float alphaScale;
|
||||
|
||||
alphaScale = 0.8f;
|
||||
HandleBoxMoving();
|
||||
|
||||
if (!m_numitems) {
|
||||
//
|
||||
// Nothing to show
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
|
||||
if (alpha > 1.0) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
alpha = (1.0 - alpha) * 4.0;
|
||||
if (alpha > 1.0) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
if (cge) {
|
||||
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
|
||||
}
|
||||
|
||||
fsY = DrawItem(m_items, s_dmboxOffsetX, s_dmboxOffsetY, alpha * alphaScale);
|
||||
fsY = alpha <= 0.2 ? s_dmboxOffsetY : fsY + s_dmboxOffsetY;
|
||||
|
||||
for (i = 1; i < m_numitems; i++) {
|
||||
fsY += DrawItem(&m_items[i], s_dmboxOffsetX, fsY, alphaScale);
|
||||
if (fsY > m_frame.size.height) {
|
||||
if (EventPending(EV_DMBox_Decay)) {
|
||||
CancelEventsOfType(EV_DMBox_Decay);
|
||||
}
|
||||
|
||||
PostEvent(EV_DMBox_Decay, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIDMBox::Draw( void )
|
||||
void UIDMBox::setRealShow(bool b)
|
||||
{
|
||||
float fsY;
|
||||
int i;
|
||||
float alpha;
|
||||
float alphaScale;
|
||||
|
||||
alphaScale = 0.8f;
|
||||
HandleBoxMoving();
|
||||
|
||||
if (!m_numitems) {
|
||||
//
|
||||
// Nothing to show
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
alpha = (1.0 - alpha) * 4.0;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
if (cge) {
|
||||
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
|
||||
}
|
||||
|
||||
fsY = DrawItem(m_items, s_dmboxOffsetX, s_dmboxOffsetY, alpha * alphaScale);
|
||||
fsY = alpha <= 0.2 ? s_dmboxOffsetY : fsY + s_dmboxOffsetY;
|
||||
|
||||
for (i = 1; i < m_numitems; i++)
|
||||
{
|
||||
fsY += DrawItem(&m_items[i], s_dmboxOffsetX, fsY, alphaScale);
|
||||
if (fsY > m_frame.size.height)
|
||||
{
|
||||
if (EventPending(EV_DMBox_Decay)) {
|
||||
CancelEventsOfType(EV_DMBox_Decay);
|
||||
}
|
||||
|
||||
PostEvent(EV_DMBox_Decay, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->m_reallyshown = b;
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void UIDMBox::setRealShow( bool b )
|
||||
void UIDMBox::Clear(void)
|
||||
{
|
||||
this->m_reallyshown = b;
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void UIDMBox::Clear( void )
|
||||
{
|
||||
m_numitems = 0;
|
||||
m_numitems = 0;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ FilePickerClass::FilePickerClass()
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
UIRect2D((uid.vidWidth - 400) / 2, (uid.vidHeight - 300) / 2, 400, 300),
|
||||
"File Picker",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
|
||||
+270
-294
@@ -40,394 +40,370 @@ Event EV_GMBox_Decay
|
||||
"Event to make the gmbox console line decay"
|
||||
);
|
||||
|
||||
static float s_gmboxWidth = 640.0;
|
||||
static float s_gmboxWidth = 640.0;
|
||||
static float s_gmboxOffsetX = 3.0f;
|
||||
static float s_gmboxOffsetY = 0.0f;
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UIGMBox, NULL )
|
||||
{
|
||||
{ &W_SizeChanged, &UIGMBox::OnSizeChanged },
|
||||
{ &EV_GMBox_Goin, &UIGMBox::MoveInEvent },
|
||||
{ &EV_GMBox_Decay, &UIGMBox::DecayEvent },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, UIGMBox, NULL) {
|
||||
{&W_SizeChanged, &UIGMBox::OnSizeChanged},
|
||||
{&EV_GMBox_Goin, &UIGMBox::MoveInEvent },
|
||||
{&EV_GMBox_Decay, &UIGMBox::DecayEvent },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIGMBox::UIGMBox()
|
||||
{
|
||||
m_numitems = 0;
|
||||
m_reallyshown = true;
|
||||
m_fontbold = NULL;
|
||||
m_boxstate = boxstate_t::box_out;
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
m_numitems = 0;
|
||||
m_reallyshown = true;
|
||||
m_fontbold = NULL;
|
||||
m_boxstate = boxstate_t::box_out;
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIGMBox::VerifyBoxOut( void )
|
||||
void UIGMBox::VerifyBoxOut(void)
|
||||
{
|
||||
PostMoveinEvent();
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out)
|
||||
{
|
||||
ChangeBoxState(boxstate_t::box_moving_out);
|
||||
}
|
||||
PostMoveinEvent();
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) {
|
||||
ChangeBoxState(boxstate_t::box_moving_out);
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::ChangeBoxState( boxstate_t state )
|
||||
void UIGMBox::ChangeBoxState(boxstate_t state)
|
||||
{
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
|
||||
if (state == box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
if (state == box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::HandleBoxMoving( void )
|
||||
void UIGMBox::HandleBoxMoving(void)
|
||||
{
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
|
||||
return;
|
||||
}
|
||||
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
if (m_boxstate == boxstate_t::box_moving_out)
|
||||
{
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta + m_frame.pos.y;
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
if (m_boxstate == boxstate_t::box_moving_out) {
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta + m_frame.pos.y;
|
||||
|
||||
if (newRect.pos.y <= 0.0)
|
||||
{
|
||||
newRect.pos.y = 0.0;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
}
|
||||
else if (m_boxstate == boxstate_t::box_moving_in)
|
||||
{
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta - m_frame.pos.y;
|
||||
if (newRect.pos.y <= 0.0) {
|
||||
newRect.pos.y = 0.0;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
} else if (m_boxstate == boxstate_t::box_moving_in) {
|
||||
newRect.size.width = m_frame.size.width;
|
||||
newRect.size.height = m_frame.size.height;
|
||||
newRect.pos.x = m_frame.pos.x;
|
||||
newRect.pos.y = delta - m_frame.pos.y;
|
||||
|
||||
if (newRect.pos.y <= -newRect.size.height)
|
||||
{
|
||||
newRect.pos.y = -newRect.size.height;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
} else {
|
||||
newRect = m_frame;
|
||||
}
|
||||
if (newRect.pos.y <= -newRect.size.height) {
|
||||
newRect.pos.y = -newRect.size.height;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
} else {
|
||||
newRect = m_frame;
|
||||
}
|
||||
|
||||
setFrame(newRect);
|
||||
setFrame(newRect);
|
||||
}
|
||||
|
||||
void UIGMBox::PostMoveinEvent( void )
|
||||
void UIGMBox::PostMoveinEvent(void)
|
||||
{
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EventPending(EV_GMBox_Goin)) {
|
||||
PostEvent(EV_GMBox_Goin, 10.0);
|
||||
} else {
|
||||
PostponeEvent(EV_GMBox_Goin, 10.0);
|
||||
}
|
||||
if (!EventPending(EV_GMBox_Goin)) {
|
||||
PostEvent(EV_GMBox_Goin, 10.0);
|
||||
} else {
|
||||
PostponeEvent(EV_GMBox_Goin, 10.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::PostDecayEvent( void )
|
||||
void UIGMBox::PostDecayEvent(void)
|
||||
{
|
||||
if (!EventPending(EV_GMBox_Decay))
|
||||
{
|
||||
float fDelayTime;
|
||||
int iNumLines;
|
||||
int i;
|
||||
const char* pszString = m_items[0].string.c_str();
|
||||
if (!EventPending(EV_GMBox_Decay)) {
|
||||
float fDelayTime;
|
||||
int iNumLines;
|
||||
int i;
|
||||
const char *pszString = m_items[0].string.c_str();
|
||||
|
||||
//
|
||||
// Calculate the number of lines
|
||||
//
|
||||
iNumLines = 1;
|
||||
for (i = 0; pszString[i]; i++)
|
||||
{
|
||||
if (pszString[i] == '\n') {
|
||||
iNumLines++;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Calculate the number of lines
|
||||
//
|
||||
iNumLines = 1;
|
||||
for (i = 0; pszString[i]; i++) {
|
||||
if (pszString[i] == '\n') {
|
||||
iNumLines++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bold as twice more decay
|
||||
//
|
||||
if (m_items[0].flags & GMBOX_ITEM_FLAG_BOLD) {
|
||||
fDelayTime = iNumLines * 10.0;
|
||||
} else {
|
||||
fDelayTime = iNumLines * 5.0;
|
||||
}
|
||||
//
|
||||
// Bold as twice more decay
|
||||
//
|
||||
if (m_items[0].flags & GMBOX_ITEM_FLAG_BOLD) {
|
||||
fDelayTime = iNumLines * 10.0;
|
||||
} else {
|
||||
fDelayTime = iNumLines * 5.0;
|
||||
}
|
||||
|
||||
m_iBeginDecay = cls.realtime;
|
||||
m_iEndDecay = (int)(fDelayTime * 1000.0);
|
||||
m_iBeginDecay = cls.realtime;
|
||||
m_iEndDecay = (int)(fDelayTime * 1000.0);
|
||||
|
||||
PostEvent(EV_GMBox_Decay, fDelayTime);
|
||||
}
|
||||
PostEvent(EV_GMBox_Decay, fDelayTime);
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::setShowState( void )
|
||||
void UIGMBox::setShowState(void)
|
||||
{
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::RemoveTopItem( void )
|
||||
void UIGMBox::RemoveTopItem(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (m_numitems > 0) {
|
||||
for (i = 0; i < m_numitems - 1; i++) {
|
||||
m_items[i] = m_items[i + 1];
|
||||
}
|
||||
if (m_numitems > 0) {
|
||||
for (i = 0; i < m_numitems - 1; i++) {
|
||||
m_items[i] = m_items[i + 1];
|
||||
}
|
||||
|
||||
m_numitems--;
|
||||
}
|
||||
m_numitems--;
|
||||
}
|
||||
}
|
||||
|
||||
str UIGMBox::CalculateBreaks( UIFont *font, str text, float max_width )
|
||||
str UIGMBox::CalculateBreaks(UIFont *font, str text, float max_width)
|
||||
{
|
||||
str newText, sTmp;
|
||||
int i;
|
||||
float fX;
|
||||
float fwX, fsX;
|
||||
str newText;
|
||||
float fX;
|
||||
float fwX;
|
||||
const char *current;
|
||||
int count;
|
||||
|
||||
Cmd_TokenizeString(text.c_str());
|
||||
if (Cmd_Argc())
|
||||
{
|
||||
fX = 0.0;
|
||||
fsX = font->getCharWidth(' ');
|
||||
current = text;
|
||||
fX = 0.0;
|
||||
|
||||
for (i = 0; i < Cmd_Argc(); i++)
|
||||
{
|
||||
sTmp = Cmd_Argv(i);
|
||||
for (count = font->DBCSGetWordBlockCount(current, -1); count;
|
||||
current += count, count = font->DBCSGetWordBlockCount(current, -1)) {
|
||||
fwX = font->getWidth(current, count);
|
||||
|
||||
fwX = font->getWidth(sTmp.c_str(), -1);
|
||||
if (fwX + i <= max_width)
|
||||
{
|
||||
if (fwX + i + fX <= max_width)
|
||||
{
|
||||
newText += sTmp + " ";
|
||||
} else {
|
||||
newText += "\n" + sTmp + " ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sTmp += "\n";
|
||||
fX = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newText = "";
|
||||
}
|
||||
if (fX + fwX > max_width) {
|
||||
newText += "\n" + str(current, 0, count);
|
||||
fX = 0;
|
||||
} else {
|
||||
newText += str(current, 0, count);
|
||||
}
|
||||
|
||||
return newText;
|
||||
fX += fwX;
|
||||
}
|
||||
|
||||
return newText;
|
||||
}
|
||||
|
||||
float UIGMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
float UIGMBox::PrintWrap(UIFont *font, float x, float y, str text)
|
||||
{
|
||||
const char* p1, * p2;
|
||||
size_t n, l;
|
||||
float fY;
|
||||
const char *p1, *p2;
|
||||
size_t n, l;
|
||||
float fY;
|
||||
|
||||
fY = y;
|
||||
p1 = text.c_str();
|
||||
l = text.length();
|
||||
fY = y;
|
||||
p1 = text.c_str();
|
||||
l = text.length();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
p2 = strchr(p1, '\n');
|
||||
if (!p2) {
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
p2 = strchr(p1, '\n');
|
||||
if (!p2) {
|
||||
break;
|
||||
}
|
||||
|
||||
n = p2 - p1;
|
||||
if (n >= l) {
|
||||
break;
|
||||
}
|
||||
n = p2 - p1;
|
||||
if (n >= l) {
|
||||
break;
|
||||
}
|
||||
|
||||
font->Print(x, fY, p1, p2 - p1, qfalse);
|
||||
p1 = p2 + 1;
|
||||
l -= n;
|
||||
fY += font->getHeight(qfalse);
|
||||
}
|
||||
font->Print(x, fY, p1, p2 - p1, getHighResScale());
|
||||
p1 = p2 + 1;
|
||||
l -= n;
|
||||
fY += font->getHeight();
|
||||
}
|
||||
|
||||
font->Print(x, fY, p1, l, qfalse);
|
||||
if (*p1) {
|
||||
font->Print(x, fY, p1, l, getHighResScale());
|
||||
fY += font->getHeight();
|
||||
}
|
||||
|
||||
return font->getHeight(qfalse) + (fY - y);
|
||||
return fY - y;
|
||||
}
|
||||
|
||||
float UIGMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
float UIGMBox::DrawItem(item_t *in, float x, float y, float alpha)
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
return PrintWrap(in->font, x, y, in->string);
|
||||
return PrintWrap(in->font, x, y, in->string);
|
||||
}
|
||||
|
||||
void UIGMBox::Print( const char *text )
|
||||
void UIGMBox::Print(const char *text)
|
||||
{
|
||||
const char* text1 = text;
|
||||
const char *text1 = text;
|
||||
|
||||
if (m_numitems > 4)
|
||||
{
|
||||
//
|
||||
// Overwrite an item
|
||||
//
|
||||
RemoveTopItem();
|
||||
}
|
||||
if (m_numitems > 4) {
|
||||
//
|
||||
// Overwrite an item
|
||||
//
|
||||
RemoveTopItem();
|
||||
}
|
||||
|
||||
m_items[m_numitems].flags = 0;
|
||||
m_items[m_numitems].flags = 0;
|
||||
|
||||
if (*text == 3)
|
||||
{
|
||||
m_items[m_numitems].color = UWhite;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= GMBOX_ITEM_FLAG_BOLD;
|
||||
if (*text == 3) {
|
||||
m_items[m_numitems].color = UWhite;
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= GMBOX_ITEM_FLAG_BOLD;
|
||||
|
||||
text1 = text + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_items[m_numitems].color = m_foreground_color;
|
||||
m_items[m_numitems].font = m_font;
|
||||
}
|
||||
text1 = text + 1;
|
||||
} else {
|
||||
m_items[m_numitems].color = m_foreground_color;
|
||||
m_items[m_numitems].font = m_font;
|
||||
}
|
||||
|
||||
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_gmboxWidth);
|
||||
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_gmboxWidth);
|
||||
|
||||
m_numitems++;
|
||||
VerifyBoxOut();
|
||||
PostDecayEvent();
|
||||
m_numitems++;
|
||||
VerifyBoxOut();
|
||||
PostDecayEvent();
|
||||
}
|
||||
|
||||
void UIGMBox::OnSizeChanged( Event *ev )
|
||||
void UIGMBox::OnSizeChanged(Event *ev)
|
||||
{
|
||||
s_gmboxWidth = m_frame.size.width;
|
||||
s_gmboxWidth = m_frame.size.width;
|
||||
}
|
||||
|
||||
void UIGMBox::Create( const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha )
|
||||
void UIGMBox::Create(const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha)
|
||||
{
|
||||
InitFrame(NULL, rect, 0, "facfont-20");
|
||||
InitFrame(NULL, rect, 0, "facfont-20");
|
||||
|
||||
if (!m_fontbold) {
|
||||
m_fontbold = new UIFont("facfont-20");
|
||||
}
|
||||
if (!m_fontbold) {
|
||||
m_fontbold = new UIFont("facfont-20");
|
||||
}
|
||||
|
||||
m_fontbold->setColor(URed);
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
m_fontbold->setColor(URed);
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
|
||||
m_movespeed = rect.size.height * 3.0;
|
||||
m_movespeed = rect.size.height * 3.0;
|
||||
|
||||
setShowState();
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void UIGMBox::MoveInEvent( Event *ev )
|
||||
void UIGMBox::MoveInEvent(Event *ev) {}
|
||||
|
||||
void UIGMBox::DecayEvent(Event *ev)
|
||||
{
|
||||
RemoveTopItem();
|
||||
if (m_numitems) {
|
||||
PostDecayEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::DecayEvent( Event *ev )
|
||||
void UIGMBox::Draw(void)
|
||||
{
|
||||
RemoveTopItem();
|
||||
if (m_numitems) {
|
||||
PostDecayEvent();
|
||||
}
|
||||
float fsY;
|
||||
int i;
|
||||
float alpha;
|
||||
float alphaScale;
|
||||
|
||||
alphaScale = 1.0;
|
||||
HandleBoxMoving();
|
||||
|
||||
if (!m_numitems) {
|
||||
//
|
||||
// Nothing to show
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
|
||||
if (alpha > 1.0) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
alpha = (1.0 - alpha) * 4.0;
|
||||
if (alpha > 1.0) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
if (cge) {
|
||||
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
|
||||
}
|
||||
|
||||
fsY = DrawItem(m_items, s_gmboxOffsetX, s_gmboxOffsetY, alpha * alphaScale);
|
||||
fsY = alpha <= 0.2 ? s_gmboxOffsetY : fsY + s_gmboxOffsetY;
|
||||
|
||||
for (i = 1; i < m_numitems; i++) {
|
||||
fsY += DrawItem(&m_items[i], s_gmboxOffsetX, fsY, alphaScale);
|
||||
if (fsY > m_frame.size.height) {
|
||||
if (EventPending(EV_GMBox_Decay)) {
|
||||
CancelEventsOfType(EV_GMBox_Decay);
|
||||
}
|
||||
|
||||
PostEvent(EV_GMBox_Decay, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIGMBox::Draw( void )
|
||||
void UIGMBox::setRealShow(bool b)
|
||||
{
|
||||
float fsY;
|
||||
int i;
|
||||
float alpha;
|
||||
float alphaScale;
|
||||
|
||||
alphaScale = 1.0;
|
||||
HandleBoxMoving();
|
||||
|
||||
if (!m_numitems) {
|
||||
//
|
||||
// Nothing to show
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
alpha = (1.0 - alpha) * 4.0;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
if (cge) {
|
||||
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
|
||||
}
|
||||
|
||||
fsY = DrawItem(m_items, s_gmboxOffsetX, s_gmboxOffsetY, alpha * alphaScale);
|
||||
fsY = alpha <= 0.2 ? s_gmboxOffsetY : fsY + s_gmboxOffsetY;
|
||||
|
||||
for (i = 1; i < m_numitems; i++)
|
||||
{
|
||||
fsY += DrawItem(&m_items[i], s_gmboxOffsetX, fsY, alphaScale);
|
||||
if (fsY > m_frame.size.height)
|
||||
{
|
||||
if (EventPending(EV_GMBox_Decay)) {
|
||||
CancelEventsOfType(EV_GMBox_Decay);
|
||||
}
|
||||
|
||||
PostEvent(EV_GMBox_Decay, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->m_reallyshown = b;
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void UIGMBox::setRealShow( bool b )
|
||||
void UIGMBox::Clear(void)
|
||||
{
|
||||
this->m_reallyshown = b;
|
||||
setShowState();
|
||||
m_numitems = 0;
|
||||
}
|
||||
|
||||
void UIGMBox::Clear( void )
|
||||
{
|
||||
m_numitems = 0;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ void FakkMiniconsole::PostMoveinEvent(void)
|
||||
|
||||
void FakkMiniconsole::OnSizeChanged(Event *ev)
|
||||
{
|
||||
m_maxlines = m_frame.size.height / m_font->getHeight(false);
|
||||
m_maxlines = m_frame.size.height / m_font->getHeight(getHighResScale());
|
||||
}
|
||||
|
||||
void FakkMiniconsole::MoveInEvent(Event *ev)
|
||||
@@ -163,14 +163,14 @@ void FakkMiniconsole::Draw(void)
|
||||
HandleBoxMoving();
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
aty = m_frame.size.height - m_font->getHeight(false);
|
||||
aty = m_frame.size.height - m_font->getHeight(getHighResScale());
|
||||
for (i = m_lines.NumObjects(); i > 0; i--) {
|
||||
if (-m_font->getHeight(false) >= aty) {
|
||||
if (-m_font->getHeight(getHighResScale()) >= aty) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false);
|
||||
aty -= m_font->getHeight(false);
|
||||
m_font->Print(0, aty / getHighResScale()[1], m_lines.ObjectAt(i), -1, getHighResScale());
|
||||
aty -= m_font->getHeight(getHighResScale());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ MpMapPickerClass::MpMapPickerClass()
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200),
|
||||
UIRect2D((uid.vidWidth - 300) / 2, (uid.vidHeight - 200) / 2, 300, 200),
|
||||
"Select a Map",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
|
||||
@@ -155,7 +155,7 @@ PlayerModelPickerClass::PlayerModelPickerClass()
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
UIRect2D((uid.vidWidth - 400) / 2, (uid.vidHeight - 300) / 2, 400, 300),
|
||||
"Player Model Select...",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
|
||||
@@ -177,6 +177,9 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
|
||||
newRect.size.height *= uid.vidHeight / 768;
|
||||
}
|
||||
*/
|
||||
|
||||
virtualScale[0] = m_parent->getHighResScale()[0];
|
||||
virtualScale[1] = m_parent->getHighResScale()[1];
|
||||
|
||||
if (!pColoringType->integer) {
|
||||
if (IfQueryFailed() || (IsDifferentVersion() && IsQueried())) {
|
||||
@@ -210,7 +213,7 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
|
||||
newRect.pos.y / virtualScale[1],
|
||||
getListItemString(iColumn).c_str(),
|
||||
-1,
|
||||
false //m_parent->isVirtual()
|
||||
virtualScale
|
||||
);
|
||||
} else {
|
||||
if (IsDifferentVersion()) {
|
||||
@@ -266,7 +269,7 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
|
||||
newRect.pos.y / virtualScale[1],
|
||||
getListItemString(iColumn).c_str(),
|
||||
-1,
|
||||
false //m_parent->isVirtual()
|
||||
virtualScale
|
||||
);
|
||||
|
||||
if (IsDifferentVersion()) {
|
||||
@@ -1181,6 +1184,11 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
}
|
||||
|
||||
iServerTotalCount += ServerListCount(serverlist);
|
||||
|
||||
// Removed in 2.0
|
||||
// Only add entries for servers that are queried successfully
|
||||
// it avoids unnecessary entries
|
||||
#if 0
|
||||
for (j = 0; j < ServerListCount(serverlist); j++) {
|
||||
GServer arrayServer = ServerListGetServer(serverlist, j);
|
||||
|
||||
@@ -1208,6 +1216,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
|
||||
uiServerList->AddItem(pNewServerItem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
for (i = 1; i <= uiServerList->getNumItems(); i++)
|
||||
|
||||
+33
-14
@@ -443,6 +443,7 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
float alpha;
|
||||
qhandle_t hMat;
|
||||
float w, h;
|
||||
float fvWidth, fvHeight;
|
||||
|
||||
col[0] = col[1] = col[2] = col[3] = 1.0;
|
||||
|
||||
@@ -488,11 +489,20 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float width = frac * m_frame.size.width;
|
||||
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
|
||||
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
|
||||
|
||||
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
|
||||
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
|
||||
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
|
||||
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
|
||||
|
||||
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
|
||||
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
@@ -521,13 +531,22 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float y = m_frame.size.height * (1.0 - frac);
|
||||
|
||||
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
|
||||
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
|
||||
|
||||
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
|
||||
//re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
re.DrawTilePic(
|
||||
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
|
||||
);
|
||||
|
||||
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
|
||||
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
|
||||
|
||||
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
|
||||
//re.DrawTilePic(
|
||||
// 0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
|
||||
//);
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
@@ -961,8 +980,8 @@ void UIFakkLabel::DrawStatRotator(float frac)
|
||||
vNeedleDir[0] = fSinVal;
|
||||
vNeedleDir[1] = -fCosVal;
|
||||
|
||||
vSize[0] = (m_frame.size.width + m_frame.size.height) / m_frame.size.width * m_angles[2] * m_vVirtualScale[0];
|
||||
vSize[1] = (m_frame.size.width + m_frame.size.height) / m_frame.size.height * m_scale * m_vVirtualScale[1];
|
||||
vSize[0] = (m_frame.size.width + m_frame.size.height) / m_frame.size.width * m_angles[2] * getVirtualScale()[0];
|
||||
vSize[1] = (m_frame.size.width + m_frame.size.height) / m_frame.size.height * m_scale * getVirtualScale()[1];
|
||||
|
||||
vCenter[0] = (m_frame.size.width * 0.5f - vSize[0]) * vNeedleDir[0] + m_frame.size.width * 0.5f;
|
||||
vCenter[1] = (m_frame.size.height * 0.5f - vSize[1]) * vNeedleDir[1] + m_frame.size.height * 0.5f;
|
||||
@@ -1357,7 +1376,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
@@ -1365,7 +1384,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
}
|
||||
return;
|
||||
@@ -1384,7 +1403,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentVertical,
|
||||
va("%d", delta),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
@@ -1392,7 +1411,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
va("%d", delta),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
}
|
||||
return;
|
||||
@@ -1478,7 +1497,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
@@ -1486,7 +1505,7 @@ void UIFakkLabel::Draw(void)
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+43
-46
@@ -124,9 +124,9 @@ void View3D::DrawFPS(void)
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight() * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
m_font->getHeight() * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -145,11 +145,11 @@ void View3D::DrawFPS(void)
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
m_font->getHeight(getHighResScale()) * 10.0 / getHighResScale()[0],
|
||||
(m_frame.pos.y + m_frame.size.height - m_font->getHeight(getHighResScale()) * 3.0) / getHighResScale()[1],
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
getHighResScale()
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
@@ -162,11 +162,11 @@ void View3D::DrawFPS(void)
|
||||
Com_sprintf(string, sizeof(string), "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
(m_font->getHeight(getHighResScale()) * 10.0) / getHighResScale()[0],
|
||||
(m_frame.pos.y + m_frame.size.height - m_font->getHeight(getHighResScale()) * 2.0) / getHighResScale()[1],
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
getHighResScale()
|
||||
);
|
||||
|
||||
Com_sprintf(
|
||||
@@ -179,11 +179,11 @@ void View3D::DrawFPS(void)
|
||||
);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
(m_font->getHeight(getHighResScale()) * 10.0) / getHighResScale()[0],
|
||||
(m_frame.pos.y + m_frame.size.height - m_font->getHeight(getHighResScale())) / getHighResScale()[1],
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
getHighResScale()
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
@@ -208,32 +208,32 @@ void View3D::PrintSound(int channel, const char *name, float vol, int rvol, floa
|
||||
float xStep;
|
||||
float height;
|
||||
|
||||
height = m_font->getHeight(false);
|
||||
height = m_font->getHeight(getHighResScale());
|
||||
xStep = height;
|
||||
|
||||
x = 0;
|
||||
Com_sprintf(buf, sizeof(buf), "%d", channel);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
x += xStep + xStep;
|
||||
Com_sprintf(buf, sizeof(buf), "%s", name);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
x += xStep * 30.0;
|
||||
Com_sprintf(buf, sizeof(buf), "vol:%.2f", vol);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
x += xStep * 8;
|
||||
Com_sprintf(buf, sizeof(buf), "rvol:%.2f", (float)(rvol / 128.f));
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
x += xStep * 5;
|
||||
Com_sprintf(buf, sizeof(buf), "pit:%.2f", pitch);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
x += xStep * 5;
|
||||
Com_sprintf(buf, sizeof(buf), "base:%d", (int)base);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, getHighResScale());
|
||||
|
||||
line++;
|
||||
}
|
||||
@@ -264,8 +264,7 @@ void DisplayServerNetProfileInfo(UIFont *font, float y, netprofclient_t *netprof
|
||||
(unsigned int)((float)(netprofile->outPackets.numFragmented + netprofile->inPackets.numFragmented)
|
||||
/ (float)(netprofile->inPackets.totalProcessed + netprofile->outPackets.totalProcessed)
|
||||
)),
|
||||
-1,
|
||||
qfalse
|
||||
-1
|
||||
);
|
||||
font->Print(334, y, va("%i", netprofile->inPackets.percentDropped));
|
||||
font->Print(364, y, va("%i", netprofile->outPackets.percentDropped));
|
||||
@@ -276,8 +275,7 @@ void DisplayServerNetProfileInfo(UIFont *font, float y, netprofclient_t *netprof
|
||||
(unsigned int)((float)(netprofile->outPackets.numDropped + netprofile->inPackets.numDropped)
|
||||
/ (float)(netprofile->inPackets.totalProcessed + netprofile->outPackets.totalProcessed)
|
||||
)),
|
||||
-1,
|
||||
qfalse
|
||||
-1
|
||||
);
|
||||
font->Print(434, y, va("%i", netprofile->inPackets.percentDropped));
|
||||
font->Print(464, y, va("%i", netprofile->outPackets.percentDropped));
|
||||
@@ -288,8 +286,7 @@ void DisplayServerNetProfileInfo(UIFont *font, float y, netprofclient_t *netprof
|
||||
(unsigned int)((float)(netprofile->outPackets.totalLengthConnectionLess
|
||||
+ netprofile->inPackets.totalLengthConnectionLess)
|
||||
/ (float)(netprofile->outPackets.totalSize + netprofile->inPackets.totalSize))),
|
||||
-1,
|
||||
qfalse
|
||||
-1
|
||||
);
|
||||
font->Print(534, y, va("%i", netprofile->inPackets.bytesPerSec));
|
||||
font->Print(594, y, va("%i", netprofile->outPackets.bytesPerSec));
|
||||
@@ -303,7 +300,7 @@ void DisplayClientNetProfile(UIFont *font, float x, float y, netprofclient_t *ne
|
||||
float fontHeight;
|
||||
float columnHeight;
|
||||
|
||||
fontHeight = font->getHeight(qfalse);
|
||||
fontHeight = font->getHeight();
|
||||
columns[0] = x + 120;
|
||||
columns[1] = x + 230;
|
||||
columns[2] = x + 330;
|
||||
@@ -402,13 +399,13 @@ void View3D::DrawNetProfile(void)
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
fontHeight = m_font->getHeight(qfalse);
|
||||
fontHeight = m_font->getHeight();
|
||||
yOffset = sv_netprofileoverlay->integer + 8;
|
||||
|
||||
if (svs.netprofile.rate) {
|
||||
m_font->Print(8, yOffset, va("Server Net Profile Max Rate: %i", svs.netprofile.rate), -1, qfalse);
|
||||
m_font->Print(8, yOffset, va("Server Net Profile Max Rate: %i", svs.netprofile.rate), -1);
|
||||
} else {
|
||||
m_font->Print(8, yOffset, "Server Net Profile Max Rate: none", -1, qfalse);
|
||||
m_font->Print(8, yOffset, "Server Net Profile Max Rate: none", -1);
|
||||
}
|
||||
|
||||
columnHeight = fontHeight + fontHeight + yOffset;
|
||||
@@ -487,10 +484,10 @@ void View3D::DrawNetProfile(void)
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
fontHeight = m_font->getHeight(qfalse);
|
||||
fontHeight = m_font->getHeight();
|
||||
yOffset = cl_netprofileoverlay->integer + 16;
|
||||
|
||||
m_font->Print(16, yOffset, "Client Net Profile", -1, qfalse);
|
||||
m_font->Print(16, yOffset, "Client Net Profile", -1);
|
||||
|
||||
NetProfileCalcStats(&cls.netprofile.outPackets, 500);
|
||||
NetProfileCalcStats(&cls.netprofile.inPackets, 500);
|
||||
@@ -567,7 +564,7 @@ void View3D::CenterPrint(void)
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
@@ -575,7 +572,7 @@ void View3D::CenterPrint(void)
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, m_bVirtual ? m_vVirtualScale : NULL
|
||||
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, getVirtualScale()
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
@@ -628,7 +625,7 @@ void View3D::LocationPrint(void)
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
x = m_x_coord / 640.f * m_screenframe.size.width;
|
||||
y = (480 - m_font->getHeight(false) - m_y_coord) / 480.f * m_screenframe.size.height;
|
||||
y = (480 - m_font->getHeight(getHighResScale()) - m_y_coord) / 480.f * m_screenframe.size.height;
|
||||
|
||||
if (m_x_coord == -1) {
|
||||
horiz = FONT_JUSTHORZ_CENTER;
|
||||
@@ -647,7 +644,7 @@ void View3D::LocationPrint(void)
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
@@ -658,7 +655,7 @@ void View3D::LocationPrint(void)
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
getVirtualScale()
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
@@ -746,7 +743,7 @@ void View3D::DrawSubtitleOverlay(void)
|
||||
{
|
||||
cvar_t *subAlpha;
|
||||
int i;
|
||||
float minX, maxY;
|
||||
float minX, maxX;
|
||||
int line;
|
||||
|
||||
subAlpha = Cvar_Get("subAlpha", "0.5", 0);
|
||||
@@ -781,8 +778,8 @@ void View3D::DrawSubtitleOverlay(void)
|
||||
}
|
||||
}
|
||||
|
||||
minX = m_screenframe.size.height - m_font->getHeight(false) * 10;
|
||||
maxY = (m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f;
|
||||
minX = m_screenframe.size.height - m_font->getHeight(getHighResScale()) * 10;
|
||||
maxX = ((m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f) / getHighResScale()[0];
|
||||
line = 0;
|
||||
|
||||
for (i = 0; i < MAX_SUBTITLES; i++) {
|
||||
@@ -790,7 +787,7 @@ void View3D::DrawSubtitleOverlay(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxY) {
|
||||
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxX) {
|
||||
char buf[2048];
|
||||
char *c;
|
||||
char *end;
|
||||
@@ -813,12 +810,12 @@ void View3D::DrawSubtitleOverlay(void)
|
||||
|
||||
width = m_font->getWidth(c, blockcount);
|
||||
|
||||
if (total + width > maxY) {
|
||||
if (total + width > maxX) {
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, buf, -1, false);
|
||||
m_font->Print(18, (m_font->getHeight(getHighResScale()) * line + minX + 1.f) / getHighResScale()[1], buf, -1, getHighResScale());
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, buf, -1, false);
|
||||
m_font->Print(20, (m_font->getHeight(getHighResScale()) * line + minX) / getHighResScale()[1], buf, -1, getHighResScale());
|
||||
|
||||
line++;
|
||||
|
||||
@@ -841,17 +838,17 @@ void View3D::DrawSubtitleOverlay(void)
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, buf, -1, qfalse);
|
||||
m_font->Print(18, (m_font->getHeight(getHighResScale()) * line + minX + 1.f) / getHighResScale()[1], buf, -1, getHighResScale());
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, buf, -1, qfalse);
|
||||
m_font->Print(20, (m_font->getHeight(getHighResScale()) * line + minX) / getHighResScale()[1], buf, -1, getHighResScale());
|
||||
line++;
|
||||
} else {
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, subs[i]->string, -1, qfalse);
|
||||
m_font->Print(18, (m_font->getHeight(getHighResScale()) * line + minX + 1.f) / getHighResScale()[1], subs[i]->string, -1, getHighResScale());
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, subs[i]->string, -1, qfalse);
|
||||
m_font->Print(20, (m_font->getHeight(getHighResScale()) * line + minX) / getHighResScale()[1], subs[i]->string, -1, getHighResScale());
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
@@ -389,6 +389,8 @@ typedef struct {
|
||||
qhandle_t whiteShader;
|
||||
qhandle_t consoleShader;
|
||||
fontInfo_t consoleFont;
|
||||
|
||||
int refSequence;
|
||||
} clientStatic_t;
|
||||
|
||||
extern clientStatic_t cls;
|
||||
@@ -557,6 +559,9 @@ void UI_LoadResource( const char *name );
|
||||
|
||||
qboolean CL_CheckPaused(void);
|
||||
|
||||
int CL_GetRefSequence(void);
|
||||
qboolean CL_IsRendererLoaded(void);
|
||||
|
||||
//
|
||||
// cl_input
|
||||
//
|
||||
|
||||
@@ -81,6 +81,7 @@ LPALGENBUFFERS qalGenBuffers;
|
||||
LPALDELETEBUFFERS qalDeleteBuffers;
|
||||
LPALISBUFFER qalIsBuffer;
|
||||
LPALBUFFERDATA qalBufferData;
|
||||
LPALBUFFERI qalBufferi;
|
||||
LPALGETBUFFERF qalGetBufferf;
|
||||
LPALGETBUFFERFV qalGetBufferfv;
|
||||
LPALGETBUFFERI qalGetBufferi;
|
||||
@@ -201,6 +202,7 @@ qboolean QAL_Init(const char *libname)
|
||||
qalDeleteBuffers = GPA("alDeleteBuffers");
|
||||
qalIsBuffer = GPA("alIsBuffer");
|
||||
qalBufferData = GPA("alBufferData");
|
||||
qalBufferi = GPA("alBufferi");
|
||||
qalGetBufferf = GPA("alGetBufferf");
|
||||
qalGetBufferfv = GPA("alGetBufferfv");
|
||||
qalGetBufferi = GPA("alGetBufferi");
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ extern LPALBUFFERDATA qalBufferData;
|
||||
extern LPALBUFFERF qalBufferf;
|
||||
extern LPALBUFFER3F qalBuffer3f;
|
||||
extern LPALBUFFERFV qalBufferfv;
|
||||
extern LPALBUFFERF qalBufferi;
|
||||
extern LPALBUFFERI qalBufferi;
|
||||
extern LPALBUFFER3F qalBuffer3i;
|
||||
extern LPALBUFFERFV qalBufferiv;
|
||||
extern LPALGETBUFFERF qalGetBufferf;
|
||||
|
||||
@@ -34,11 +34,12 @@ extern "C" {
|
||||
typedef struct snd_info_s
|
||||
{
|
||||
int rate;
|
||||
int width;
|
||||
float width;
|
||||
int channels;
|
||||
int samples;
|
||||
int size;
|
||||
int dataofs;
|
||||
int dataalign;
|
||||
} snd_info_t;
|
||||
|
||||
typedef struct snd_codec_s snd_codec_t;
|
||||
|
||||
@@ -622,7 +622,7 @@ int S_MP3_CodecReadStream(snd_stream_t* stream, int bytes, void* buffer)
|
||||
mp3info = stream->ptr;
|
||||
|
||||
// Make sure we get complete frames all the way through.
|
||||
bytes -= bytes % (stream->info.channels * stream->info.width);
|
||||
bytes -= fmod(bytes, (stream->info.channels * stream->info.width));
|
||||
|
||||
if (mp3info->buflen)
|
||||
{
|
||||
|
||||
@@ -133,6 +133,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
|
||||
char dump[16];
|
||||
int bits;
|
||||
int fmtlen = 0;
|
||||
int bytealign;
|
||||
|
||||
// skip the riff wav header
|
||||
FS_Read(dump, 12, file);
|
||||
@@ -149,17 +150,22 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
|
||||
info->channels = FGetLittleShort(file);
|
||||
info->rate = FGetLittleLong(file);
|
||||
FGetLittleLong(file);
|
||||
FGetLittleShort(file);
|
||||
bytealign = FGetLittleShort(file);
|
||||
bits = FGetLittleShort(file);
|
||||
|
||||
if( bits < 8 )
|
||||
{
|
||||
Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n");
|
||||
return qfalse;
|
||||
}
|
||||
//if( bits < 8 )
|
||||
//{
|
||||
// Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n");
|
||||
// return qfalse;
|
||||
//}
|
||||
|
||||
info->width = bits / 8;
|
||||
info->width = bits / 8.0;
|
||||
info->dataofs = 0;
|
||||
if (bits == 16) {
|
||||
info->dataalign = 1;
|
||||
} else {
|
||||
info->dataalign = (bytealign / info->channels - 4) / 4 * 8 + 1;
|
||||
}
|
||||
|
||||
// Skip the rest of the format chunk if required
|
||||
if(fmtlen > 16)
|
||||
|
||||
@@ -104,7 +104,7 @@ void S_Init(qboolean full_startup)
|
||||
s_musicVolume = Cvar_Get("s_musicvolume", "0.9", CVAR_ARCHIVE);
|
||||
s_ambientVolume = Cvar_Get("s_ambientvolume", "1.00", CVAR_ARCHIVE);
|
||||
s_separation = Cvar_Get("s_separation", "0.5", CVAR_ARCHIVE);
|
||||
s_khz = Cvar_Get("s_khz", "11", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
|
||||
s_khz = Cvar_Get("s_khz", "44", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
|
||||
s_loadas8bit = Cvar_Get("s_loadas8bit", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
s_mixPreStep = Cvar_Get("s_mixPreStep", "0.05", CVAR_ARCHIVE);
|
||||
s_show = Cvar_Get("s_show", "0", CVAR_CHEAT);
|
||||
@@ -552,7 +552,7 @@ void S_StartLocalSound(const char *sound_name, qboolean force_load)
|
||||
}
|
||||
|
||||
S_StartSound(
|
||||
0,
|
||||
NULL,
|
||||
s_iListenerNumber,
|
||||
CHAN_MENU,
|
||||
sfxHandle,
|
||||
@@ -749,6 +749,10 @@ void S_Play()
|
||||
int i;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
if (Cmd_Argc() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++) {
|
||||
if (strrchr(Cmd_Argv(i), '.')) {
|
||||
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef struct {
|
||||
|
||||
int dataofs;
|
||||
int datasize;
|
||||
int dataalign;
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct sfx_s {
|
||||
|
||||
+63
-61
@@ -43,13 +43,13 @@ short int GetLittleShort()
|
||||
byte bytes[2];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
# else
|
||||
#else
|
||||
val.bytes[0] = data_p[1];
|
||||
val.bytes[1] = data_p[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
return val.value;
|
||||
@@ -67,17 +67,17 @@ int GetLittleLong()
|
||||
byte bytes[4];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
val.bytes[2] = data_p[2];
|
||||
val.bytes[3] = data_p[3];
|
||||
# else
|
||||
#else
|
||||
val.bytes[0] = data_p[3];
|
||||
val.bytes[1] = data_p[2];
|
||||
val.bytes[2] = data_p[1];
|
||||
val.bytes[3] = data_p[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
return val.value;
|
||||
@@ -97,13 +97,13 @@ void SetLittleShort(int i)
|
||||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
# else
|
||||
#else
|
||||
data_p[0] = val.bytes[1];
|
||||
data_p[1] = val.bytes[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
}
|
||||
@@ -122,17 +122,17 @@ void SetLittleLong(int i)
|
||||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
data_p[2] = val.bytes[2];
|
||||
data_p[3] = val.bytes[3];
|
||||
# else
|
||||
#else
|
||||
data_p[0] = val.bytes[3];
|
||||
data_p[1] = val.bytes[2];
|
||||
data_p[2] = val.bytes[1];
|
||||
data_p[3] = val.bytes[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
}
|
||||
@@ -218,6 +218,7 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
||||
{
|
||||
wavinfo_t info;
|
||||
int samples;
|
||||
short bytealign;
|
||||
|
||||
memset(&info, 0, sizeof(wavinfo_t));
|
||||
|
||||
@@ -247,7 +248,9 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
||||
if (info.format == 17) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
data_p += 4;
|
||||
|
||||
bytealign = GetLittleShort();
|
||||
info.width = (float)GetLittleShort() / 8.f;
|
||||
data_p += 2;
|
||||
|
||||
@@ -270,12 +273,16 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
||||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = 0;
|
||||
info.dataofs = data_p - wav;
|
||||
info.datasize = iff_chunk_len - bytealign + info.dataofs;
|
||||
info.dataalign = (bytealign / info.channels - 4) / 4 * 8 + 1;
|
||||
} else if (info.format == 1) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
info.width = (float)(GetLittleShort() / 8);
|
||||
data_p += 4;
|
||||
|
||||
bytealign = GetLittleShort();
|
||||
info.width = (float)GetLittleShort() / 8.f;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p) {
|
||||
@@ -292,14 +299,16 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
||||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = data_p - wav;
|
||||
info.dataofs = data_p - wav;
|
||||
info.datasize = iff_chunk_len;
|
||||
info.dataalign = (bytealign / info.channels - 4) / 4 * 8 + 1;
|
||||
// dataalign should always be 1
|
||||
assert(info.dataalign == 1);
|
||||
} else {
|
||||
Com_Printf("Microsoft PCM format only\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
info.datasize = iff_chunk_len;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -310,26 +319,24 @@ DownSampleWav
|
||||
*/
|
||||
qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
|
||||
{
|
||||
int newdatasize;
|
||||
byte* datap;
|
||||
int i;
|
||||
int ii;
|
||||
int error;
|
||||
int width;
|
||||
int oldsamples;
|
||||
int oldrate;
|
||||
int newdatasize;
|
||||
byte *datap;
|
||||
int i;
|
||||
int ii;
|
||||
int error;
|
||||
int width;
|
||||
int oldsamples;
|
||||
int oldrate;
|
||||
|
||||
newdatasize = 0;
|
||||
datap = &wav[info->dataofs];
|
||||
datap = &wav[info->dataofs];
|
||||
|
||||
if (info->channels > 1)
|
||||
{
|
||||
if (info->channels > 1) {
|
||||
Com_DPrintf("Could not downsample WAV file. Stereo WAVs not supported!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->format != 1 || !info->dataofs)
|
||||
{
|
||||
if (info->format != 1 || !info->dataofs) {
|
||||
Com_DPrintf("Could not downsample WAV file. Not PCM format!\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -348,29 +355,27 @@ qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, by
|
||||
}
|
||||
}
|
||||
|
||||
oldsamples = info->samples;
|
||||
oldrate = info->rate;
|
||||
oldsamples = info->samples;
|
||||
oldrate = info->rate;
|
||||
info->samples = newdatasize / width;
|
||||
info->rate = (float)newkhz;
|
||||
info->rate = (float)newkhz;
|
||||
newdatasize += info->dataofs;
|
||||
|
||||
*newdata = (byte*)Z_TagMalloc(newdatasize, TAG_SOUND);
|
||||
*newdata = (byte *)Z_TagMalloc(newdatasize, TAG_SOUND);
|
||||
memcpy(*newdata, wav, info->dataofs);
|
||||
|
||||
iff_data = *newdata;
|
||||
iff_end = *newdata + newdatasize;
|
||||
iff_end = *newdata + newdatasize;
|
||||
FindChunk("RIFF");
|
||||
|
||||
if (!data_p || strncmp((const char*)data_p + 8, "WAVE", 4u))
|
||||
{
|
||||
if (!data_p || strncmp((const char *)data_p + 8, "WAVE", 4u)) {
|
||||
Com_DPrintf("Missing RIFF/WAVE chunks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
iff_data = data_p + 12;
|
||||
FindChunk("fmt ");
|
||||
if (!data_p)
|
||||
{
|
||||
if (!data_p) {
|
||||
Com_DPrintf("Missing fmt chunk\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -380,8 +385,7 @@ qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, by
|
||||
data_p += 8;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p)
|
||||
{
|
||||
if (!data_p) {
|
||||
Com_DPrintf("Missing data chunk\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -427,10 +431,10 @@ S_LoadSound
|
||||
*/
|
||||
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load)
|
||||
{
|
||||
int size;
|
||||
int size;
|
||||
fileHandle_t file_handle;
|
||||
char tempName[MAX_RES_NAME + 1];
|
||||
int realKhz;
|
||||
char tempName[MAX_RES_NAME + 1];
|
||||
int realKhz;
|
||||
|
||||
sfx->buffer = 0;
|
||||
|
||||
@@ -440,10 +444,10 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
|
||||
if (streamed) {
|
||||
sfx->length = 5000;
|
||||
sfx->width = 1;
|
||||
sfx->width = 1;
|
||||
sfx->iFlags |= SFX_FLAG_STREAMED;
|
||||
sfx->time_length = 5000.0;
|
||||
sfx->data = NULL;
|
||||
sfx->data = NULL;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
@@ -456,22 +460,20 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
}
|
||||
|
||||
size = FS_FOpenFileRead(fileName, &file_handle, qfalse, qtrue);
|
||||
if (size <= 0)
|
||||
{
|
||||
if (size <= 0) {
|
||||
if (file_handle) {
|
||||
FS_FCloseFile(file_handle);
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sfx->data = (byte*)Z_TagMalloc(size, TAG_SOUND);
|
||||
sfx->data = (byte *)Z_TagMalloc(size, TAG_SOUND);
|
||||
|
||||
FS_Read(sfx->data, size, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
sfx->info = GetWavinfo(fileName, sfx->data, size);
|
||||
|
||||
if (sfx->info.channels != 1 && !streamed)
|
||||
{
|
||||
if (sfx->info.channels != 1 && !streamed) {
|
||||
Com_Printf("%s is a stereo wav file\n", fileName);
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = NULL;
|
||||
@@ -496,8 +498,8 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
}
|
||||
|
||||
if (!(sfx->iFlags & SFX_FLAG_STREAMED) && realKhz < sfx->info.rate) {
|
||||
byte* newdata;
|
||||
int newdatasize;
|
||||
byte *newdata;
|
||||
int newdatasize;
|
||||
|
||||
newdata = NULL;
|
||||
if (sfx->iFlags & SFX_FLAG_NO_OFFSET) {
|
||||
@@ -508,13 +510,13 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
|
||||
if (newdatasize) {
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = newdata;
|
||||
sfx->data = newdata;
|
||||
sfx->info.datasize = newdatasize;
|
||||
}
|
||||
}
|
||||
|
||||
sfx->length = sfx->info.samples;
|
||||
sfx->width = sfx->info.width;
|
||||
sfx->length = sfx->info.samples;
|
||||
sfx->width = sfx->info.width;
|
||||
sfx->time_length = sfx->info.samples / sfx->info.rate * 1000.f;
|
||||
|
||||
if (sfx->iFlags & SFX_FLAG_STREAMED) {
|
||||
@@ -540,7 +542,7 @@ S_LoadMP3
|
||||
*/
|
||||
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
|
||||
{
|
||||
int length;
|
||||
int length;
|
||||
fileHandle_t file_handle;
|
||||
|
||||
length = FS_FOpenFileRead(fileName, &file_handle, 0, 1);
|
||||
@@ -552,9 +554,9 @@ qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
|
||||
}
|
||||
|
||||
memset(&sfx->info, 0, sizeof(sfx->info));
|
||||
sfx->data = (byte*)Z_TagMalloc(length, TAG_SOUND);
|
||||
sfx->data = (byte *)Z_TagMalloc(length, TAG_SOUND);
|
||||
sfx->length = length;
|
||||
sfx->width = 1;
|
||||
sfx->width = 1;
|
||||
FS_Read(sfx->data, length, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
|
||||
|
||||
+123
-22
@@ -100,6 +100,9 @@ int music_currentsong = 0;
|
||||
static qboolean enumeration_ext = qfalse;
|
||||
static qboolean enumeration_all_ext = qfalse;
|
||||
|
||||
static qboolean ima4_ext = qfalse;
|
||||
static qboolean soft_block_align = qfalse;
|
||||
|
||||
song_t music_songs[MAX_MUSIC_SONGS];
|
||||
openal_internal_t openal;
|
||||
static float s_fFadeStartTime;
|
||||
@@ -113,7 +116,7 @@ static int
|
||||
S_OPENAL_SpatializeStereoSound(const vec3_t listener_origin, const vec3_t listener_left, const vec3_t origin);
|
||||
static void S_OPENAL_reverb(int iChannel, int iReverbType, float fReverbLevel);
|
||||
static bool S_OPENAL_LoadMP3_Codec(const char *_path, sfx_t *pSfx);
|
||||
static ALuint S_OPENAL_Format(int width, int channels);
|
||||
static ALuint S_OPENAL_Format(float width, int channels);
|
||||
|
||||
#define alDieIfError() __alDieIfError(__FILE__, __LINE__)
|
||||
|
||||
@@ -449,7 +452,9 @@ S_OPENAL_InitExtensions
|
||||
*/
|
||||
static bool S_OPENAL_InitExtensions()
|
||||
{
|
||||
Com_Printf("AL extensions ignored\n");
|
||||
ima4_ext = qalIsExtensionPresent("AL_EXT_IMA4");
|
||||
soft_block_align = qalIsExtensionPresent("AL_SOFT_block_alignment");
|
||||
|
||||
return true;
|
||||
|
||||
extensions_table_t extensions_table[4] = {
|
||||
@@ -594,6 +599,7 @@ qboolean S_OPENAL_Init()
|
||||
Com_Printf("OpenAL: No reverb support. Reverb is disabled.\n");
|
||||
}
|
||||
}
|
||||
s_reverb->modified = false;
|
||||
|
||||
al_current_volume = Square(s_volume->value);
|
||||
qalListenerf(AL_GAIN, al_current_volume);
|
||||
@@ -612,7 +618,9 @@ qboolean S_OPENAL_Init()
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM; i++) {
|
||||
if (!S_OPENAL_InitChannel(i + MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D, &openal.chan_2D_stream[i])) {
|
||||
if (!S_OPENAL_InitChannel(
|
||||
i + MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D, &openal.chan_2D_stream[i]
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -638,6 +646,17 @@ qboolean S_OPENAL_Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Disable sound virtualization on special channels
|
||||
// (triggered music, ambient sounds...)
|
||||
//
|
||||
for (i = 0; i < MAX_SOUNDSYSTEM_SONGS; i++) {
|
||||
openal.chan_song[i].set_no_virtualization();
|
||||
}
|
||||
openal.chan_mp3.set_no_virtualization();
|
||||
openal.chan_trig_music.set_no_virtualization();
|
||||
openal.chan_movie.set_no_virtualization();
|
||||
|
||||
Cmd_AddCommand("playmp3", S_OPENAL_PlayMP3);
|
||||
Cmd_AddCommand("stopmp3", S_OPENAL_StopMP3);
|
||||
Cmd_AddCommand("loadsoundtrack", S_loadsoundtrack);
|
||||
@@ -827,7 +846,8 @@ void S_DumpInfo()
|
||||
S_DumpStatus(
|
||||
"Misc",
|
||||
i,
|
||||
openal.channel[MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + i]
|
||||
openal.channel
|
||||
[MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + i]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1357,16 +1377,15 @@ static void S_OPENAL_Start2DSound(
|
||||
pChannel->iBaseRate = pChannel->sample_playback_rate();
|
||||
pChannel->set_no_3d();
|
||||
fRealVolume = fRealVolume * s_fVolumeGain;
|
||||
pChannel->set_gain(fRealVolume);
|
||||
pChannel->play();
|
||||
} else {
|
||||
pChannel->stop();
|
||||
pChannel->set_no_3d();
|
||||
pChannel->set_sfx(pSfx);
|
||||
pChannel->set_gain(fRealVolume);
|
||||
pChannel->play();
|
||||
}
|
||||
|
||||
pChannel->set_gain(fRealVolume);
|
||||
pChannel->play();
|
||||
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf(
|
||||
"OpenAL: 2D - %d (#%i) - %s (vol %f, mindist %f, maxdist %f)\n",
|
||||
@@ -1818,7 +1837,9 @@ static int S_OPENAL_Start2DLoopSound(
|
||||
pChannel->set_gain(fVolumeToPlay);
|
||||
pChannel->start_sample();
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("OpenAL: %d (#%i) - %s (vol %f)\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name, fVolume);
|
||||
Com_DPrintf(
|
||||
"OpenAL: %d (#%i) - %s (vol %f)\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name, fVolume
|
||||
);
|
||||
}
|
||||
|
||||
return iChannel;
|
||||
@@ -2138,7 +2159,9 @@ void S_OPENAL_AddLoopSounds(const vec3_t vTempAxis)
|
||||
}
|
||||
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("OpenAL: %d (#%i) - started loop - %s\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name);
|
||||
Com_DPrintf(
|
||||
"OpenAL: %d (#%i) - started loop - %s\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name
|
||||
);
|
||||
}
|
||||
|
||||
if (pLoopSound->pSfx->iFlags & (SFX_FLAG_NO_OFFSET)
|
||||
@@ -2389,7 +2412,10 @@ S_OPENAL_reverb
|
||||
*/
|
||||
static void S_OPENAL_reverb(int iChannel, int iReverbType, float fReverbLevel)
|
||||
{
|
||||
// No reverb.
|
||||
// FIXME: Connect source to effect slot
|
||||
// see https://github.com/kcat/openal-soft/blob/master/examples/alreverb.c
|
||||
|
||||
// No reverb currently.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2404,6 +2430,10 @@ void S_OPENAL_SetReverb(int iType, float fLevel)
|
||||
if (al_use_reverb) {
|
||||
s_bReverbChanged = true;
|
||||
}
|
||||
|
||||
// FIXME: generate effect and auxiliary effect slot
|
||||
// or destroy them
|
||||
// see https://github.com/kcat/openal-soft/blob/master/examples/alreverb.c
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2475,7 +2505,16 @@ void S_OPENAL_Update()
|
||||
|
||||
if (s_reverb->modified) {
|
||||
s_reverb->modified = false;
|
||||
Com_Printf("FIXME: Allow reverb toggle at runtime in OpenAL code.\n");
|
||||
|
||||
if (s_reverb->integer) {
|
||||
if (al_use_reverb) {
|
||||
S_OPENAL_SetReverb(s_iReverbType, s_fReverbLevel);
|
||||
} else {
|
||||
Com_Printf("OpenAL: No reverb support. Reverb is disabled.\n");
|
||||
}
|
||||
} else if (al_use_reverb) {
|
||||
S_OPENAL_SetReverb(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_show_num_active_sounds->integer == 1) {
|
||||
@@ -2883,6 +2922,35 @@ void openal_channel::play()
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
openal_channel::set_no_virtualization
|
||||
==============
|
||||
*/
|
||||
void openal_channel::set_no_virtualization()
|
||||
{
|
||||
#if AL_SOFT_direct_channels_remix
|
||||
qalSourcei(source, AL_DIRECT_CHANNELS_SOFT, AL_REMIX_UNMATCHED_SOFT);
|
||||
alDieIfError();
|
||||
#elif AL_SOFT_direct_channels
|
||||
qalSourcei(source, AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
|
||||
alDieIfError();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
openal_channel::set_virtualization
|
||||
==============
|
||||
*/
|
||||
void openal_channel::set_virtualization()
|
||||
{
|
||||
#if AL_SOFT_direct_channels_remix || AL_SOFT_direct_channels
|
||||
qalSourcei(source, AL_DIRECT_CHANNELS_SOFT, AL_FALSE);
|
||||
alDieIfError();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
openal_channel::pause
|
||||
@@ -2991,9 +3059,21 @@ bool openal_channel::set_sfx(sfx_t *pSfx)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pSfx->info.dataalign > 1 && !soft_block_align) {
|
||||
Com_DPrintf(
|
||||
"OpenAL: Alignment specified but AL doesn't support block alignment (%d).", pSfx->info.dataalign
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
qalGenBuffers(1, &pSfx->buffer);
|
||||
alDieIfError();
|
||||
|
||||
if (pSfx->info.dataalign > 1) {
|
||||
qalBufferi(pSfx->buffer, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, pSfx->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(
|
||||
pSfx->buffer,
|
||||
fmt,
|
||||
@@ -4216,7 +4296,7 @@ int S_CurrentMoviePosition()
|
||||
S_AL_Format
|
||||
=================
|
||||
*/
|
||||
static ALuint S_OPENAL_Format(int width, int channels)
|
||||
static ALuint S_OPENAL_Format(float width, int channels)
|
||||
{
|
||||
ALuint format = AL_FORMAT_MONO16;
|
||||
|
||||
@@ -4233,6 +4313,17 @@ static ALuint S_OPENAL_Format(int width, int channels)
|
||||
} else if (channels == 2) {
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
} else if (width == 0.5) {
|
||||
if (ima4_ext && soft_block_align) {
|
||||
if (channels == 1) {
|
||||
format = AL_FORMAT_MONO_IMA4;
|
||||
} else if (channels == 2) {
|
||||
format = AL_FORMAT_STEREO_IMA4;
|
||||
}
|
||||
} else {
|
||||
// unsupported
|
||||
format = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
@@ -4360,6 +4451,11 @@ bool openal_channel_two_d_stream::set_sfx(sfx_t *pSfx)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stream->info.dataalign > 1 && soft_block_align) {
|
||||
qalBufferi(buffers[currentBuf], AL_UNPACK_BLOCK_ALIGNMENT_SOFT, stream->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(buffers[currentBuf], pSfx->info.format, rawData, bytesRead, stream->info.rate);
|
||||
alDieIfError();
|
||||
|
||||
@@ -4499,6 +4595,11 @@ void openal_channel_two_d_stream::update()
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->info.dataalign > 1 && soft_block_align) {
|
||||
qalBufferi(buffers[currentBuf], AL_UNPACK_BLOCK_ALIGNMENT_SOFT, stream->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(buffers[currentBuf], format, rawData, bytesRead, stream->info.rate);
|
||||
alDieIfError();
|
||||
|
||||
@@ -4527,7 +4628,7 @@ U32 openal_channel_two_d_stream::sample_offset()
|
||||
ALint numProcessedBuffers = 0;
|
||||
ALint numQueuedBuffers = 0;
|
||||
unsigned int totalQueueLength = 0;
|
||||
unsigned int bytesPerSample = 0;
|
||||
unsigned int bitsPerSample = 0;
|
||||
unsigned int offset = 0;
|
||||
ALint bits = 0, channels = 0;
|
||||
|
||||
@@ -4541,7 +4642,7 @@ U32 openal_channel_two_d_stream::sample_offset()
|
||||
alDieIfError();
|
||||
|
||||
totalQueueLength = getQueueLength();
|
||||
bytesPerSample = getBytesPerSample();
|
||||
bitsPerSample = getBitsPerSample();
|
||||
|
||||
assert(playerByteOffset < totalQueueLength);
|
||||
assert(streamNextOffset >= totalQueueLength || stream);
|
||||
@@ -4569,7 +4670,7 @@ U32 openal_channel_two_d_stream::sample_offset()
|
||||
offset = totalQueueLength - streamNextOffset + playerByteOffset;
|
||||
}
|
||||
|
||||
return offset / bytesPerSample;
|
||||
return offset * 8 / bitsPerSample;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4599,7 +4700,7 @@ void openal_channel_two_d_stream::set_sample_offset(U32 offset)
|
||||
snd_stream_t *stream;
|
||||
unsigned int bytesToRead, bytesRead;
|
||||
unsigned int byteOffset;
|
||||
unsigned int bytesPerSample;
|
||||
unsigned int bitsPerSample;
|
||||
unsigned int streamPosition;
|
||||
ALuint format;
|
||||
ALint numQueuedBuffers;
|
||||
@@ -4612,8 +4713,8 @@ void openal_channel_two_d_stream::set_sample_offset(U32 offset)
|
||||
|
||||
stream = (snd_stream_t *)streamHandle;
|
||||
streamPosition = getCurrentStreamPosition();
|
||||
bytesPerSample = getBytesPerSample();
|
||||
byteOffset = offset * bytesPerSample;
|
||||
bitsPerSample = getBitsPerSample();
|
||||
byteOffset = offset * bitsPerSample / 8;
|
||||
|
||||
if (byteOffset >= streamPosition && byteOffset < streamNextOffset) {
|
||||
//
|
||||
@@ -4863,13 +4964,13 @@ unsigned int openal_channel_two_d_stream::getCurrentStreamPosition() const
|
||||
|
||||
/*
|
||||
==============
|
||||
openal_channel_two_d_stream::getBytesPerSample
|
||||
openal_channel_two_d_stream::getBitsPerSample
|
||||
|
||||
Return the number of bytes per sample.
|
||||
It assumes that all pending buffers have the same channels and bits.
|
||||
==============
|
||||
*/
|
||||
unsigned int openal_channel_two_d_stream::getBytesPerSample() const
|
||||
unsigned int openal_channel_two_d_stream::getBitsPerSample() const
|
||||
{
|
||||
unsigned int bufferId;
|
||||
ALint bits = 0, channels = 0;
|
||||
@@ -4880,5 +4981,5 @@ unsigned int openal_channel_two_d_stream::getBytesPerSample() const
|
||||
qalGetBufferi(buffers[bufferId], AL_CHANNELS, &channels);
|
||||
alDieIfError();
|
||||
|
||||
return bits * channels / 8;
|
||||
return bits * channels;
|
||||
}
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
|
||||
void set_no_3d();
|
||||
void set_3d();
|
||||
void set_no_virtualization();
|
||||
void set_virtualization();
|
||||
|
||||
void set_gain(float gain);
|
||||
void set_velocity(float v0, float v1, float v2);
|
||||
@@ -165,7 +167,7 @@ private:
|
||||
|
||||
unsigned int getQueueLength() const;
|
||||
unsigned int getCurrentStreamPosition() const;
|
||||
unsigned int getBytesPerSample() const;
|
||||
unsigned int getBitsPerSample() const;
|
||||
};
|
||||
|
||||
struct openal_movie_channel : public openal_channel {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(fgame)
|
||||
|
||||
# Shared source files for modules
|
||||
|
||||
@@ -71,9 +71,14 @@ void cVehicleSlot::NotSolid(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!ent->IsSubclassOfPlayer()) {
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
// Added in 2.0
|
||||
// Commented in OPM
|
||||
// Not sure why since 2.0, players aren't made non-solid in slots
|
||||
//if (!ent->IsSubclassOfPlayer()) {
|
||||
// ent->setSolidType(SOLID_NOT);
|
||||
//}
|
||||
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
|
||||
void cVehicleSlot::Solid(void)
|
||||
|
||||
@@ -2993,6 +2993,7 @@ Actor::Actor()
|
||||
// The variable isn't set in original
|
||||
//
|
||||
m_bSilent = false;
|
||||
m_bMumble = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -8389,7 +8390,7 @@ bool Actor::AttackEntryAnimation(void)
|
||||
m_bNewEnemy = true;
|
||||
return true;
|
||||
}
|
||||
} else if (fDistSquared > Square(1024)) {
|
||||
} else if (fDistSquared > Square(1024) && (rand() % 4) == 0) {
|
||||
Sentient *pSquadMate;
|
||||
|
||||
for (pSquadMate = m_pNextSquadMate; pSquadMate != this; pSquadMate = pSquadMate->m_pNextSquadMate) {
|
||||
@@ -8701,7 +8702,7 @@ void Actor::FaceEnemyOrMotion(int iTimeIntoMove)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
|
||||
VectorCopy2D(origin, vDelta);
|
||||
VectorSub2D(origin, m_vLastEnemyPos, vDelta);
|
||||
|
||||
if (iTimeIntoMove <= 999) {
|
||||
m_bFaceEnemy = true;
|
||||
|
||||
@@ -717,6 +717,16 @@ static void PM_NoclipMove(void)
|
||||
|
||||
// move
|
||||
VectorMA(pm->ps->origin, pml.frametime, pm->ps->velocity, pm->ps->origin);
|
||||
|
||||
// Added in 2.0
|
||||
// If the player is out of bounds in noclip mode,
|
||||
// teleport it back to the (0,0,0) coordinates
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (fabs(pm->ps->origin[i]) >= MAX_MAP_BOUNDS - 512) {
|
||||
VectorClear(pm->ps->origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -652,7 +652,7 @@ movement on the server game.
|
||||
#define MASK_CAMERASOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_BODY | MASK_WATER)
|
||||
#define MASK_BEAM (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_FENCE)
|
||||
#define MASK_LADDER \
|
||||
(CONTENTS_SOLID | CONTENTS_LADDER | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_FENCE)
|
||||
(CONTENTS_SOLID | CONTENTS_LADDER | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_FENCE | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_AUTOCALCLIFE (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_FENCE)
|
||||
#define MASK_EXPLOSION (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_WEAPONCLIP)
|
||||
#define MASK_SOUND (CONTENTS_SOLID | CONTENTS_TRANSLUCENT)
|
||||
|
||||
+19
-19
@@ -130,14 +130,14 @@ static PlayerStart *GetRandomSpawnpointFromList(spawnsort_t *pSpots, int nSpots)
|
||||
}
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Ffa(const float *origin, DM_Team *dmTeam, const Player *player)
|
||||
float SpawnpointMetric_Ffa(const vec3_t origin, DM_Team *dmTeam, const Player *player)
|
||||
{
|
||||
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
|
||||
float fMinEnemyDistSquared = Square(23170);
|
||||
int i;
|
||||
int nPlayers = dmManager.PlayerCount();
|
||||
float fDist;
|
||||
|
||||
for (i = 1; i < nPlayers; i++) {
|
||||
for (i = 1; i <= nPlayers; i++) {
|
||||
Player *teammate = dmManager.GetPlayer(i);
|
||||
if (teammate == player || teammate->IsDead() || teammate->IsSpectator()) {
|
||||
continue;
|
||||
@@ -150,12 +150,12 @@ float SpawnpointMetric_Ffa(const float *origin, DM_Team *dmTeam, const Player *p
|
||||
}
|
||||
}
|
||||
|
||||
return fMinEnemyDistSquared - (G_Random(0.25f) + 1.0f) * (1024.0f * 1024.0f);
|
||||
return fMinEnemyDistSquared - (G_Random(0.25f) + 1.0f) * Square(1024);
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Team(const float *origin, DM_Team *dmTeam, const Player *player)
|
||||
float SpawnpointMetric_Team(const vec3_t origin, DM_Team *dmTeam, const Player *player)
|
||||
{
|
||||
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
|
||||
float fMinEnemyDistSquared = Square(23170);
|
||||
float fSumFriendDistSquared = 0.0f;
|
||||
float fDistSquared;
|
||||
float fMetric;
|
||||
@@ -163,7 +163,7 @@ float SpawnpointMetric_Team(const float *origin, DM_Team *dmTeam, const Player *
|
||||
int nPlayers = dmManager.PlayerCount();
|
||||
int nFriends = 0;
|
||||
|
||||
for (i = 1; i < nPlayers; i++) {
|
||||
for (i = 1; i <= nPlayers; i++) {
|
||||
Player *teammate = dmManager.GetPlayer(i);
|
||||
if (teammate == player || teammate->IsDead() || teammate->IsSpectator()) {
|
||||
continue;
|
||||
@@ -174,14 +174,12 @@ float SpawnpointMetric_Team(const float *origin, DM_Team *dmTeam, const Player *
|
||||
if (teammate->GetDM_Team() == dmTeam) {
|
||||
nFriends++;
|
||||
fSumFriendDistSquared += fDistSquared;
|
||||
} else {
|
||||
if (fMinEnemyDistSquared > fDistSquared) {
|
||||
fMinEnemyDistSquared = fDistSquared;
|
||||
}
|
||||
} else if (fMinEnemyDistSquared > fDistSquared) {
|
||||
fMinEnemyDistSquared = fDistSquared;
|
||||
}
|
||||
}
|
||||
|
||||
fMetric = fMinEnemyDistSquared - (G_Random(0.25f) + 1.0f) * (1024.0f * 1024.0f);
|
||||
fMetric = fMinEnemyDistSquared - (G_Random(0.25f) + 1.0f) * Square(1024);
|
||||
|
||||
if (nFriends) {
|
||||
fMetric += 0.25f * ((23170.0f * 23170.0f) - fSumFriendDistSquared / nFriends);
|
||||
@@ -190,9 +188,9 @@ float SpawnpointMetric_Team(const float *origin, DM_Team *dmTeam, const Player *
|
||||
return fMetric;
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Objective(const float *origin, DM_Team *dmTeam, const Player *player)
|
||||
float SpawnpointMetric_Objective(const vec3_t origin, DM_Team *dmTeam, const Player *player)
|
||||
{
|
||||
return rand() * 0.0000000005f;
|
||||
return rand() / (float)RAND_MAX;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(Listener, DM_Team, NULL) {
|
||||
@@ -459,12 +457,12 @@ PlayerStart *DM_Team::GetRandomSpawnpointWithMetric(
|
||||
vNewSpawn, player->mins, player->maxs, vEnd, player, MASK_PLAYERSOLID, qfalse, "TempSpawnPoint"
|
||||
);
|
||||
|
||||
if (!trace.allsolid && !trace.startsolid && trace.fraction != 1.0f && trace.fraction != 1.0f
|
||||
&& trace.plane.dist >= 0.8f) {
|
||||
if (!trace.allsolid && !trace.startsolid && trace.fraction != 1.0f && trace.plane.dist >= 0.8f) {
|
||||
points[numSpots].spawnpoint = new PlayerStart;
|
||||
points[numSpots].spawnpoint->setOrigin(trace.endpos);
|
||||
points[numSpots].spawnpoint->setAngles(spot->angles);
|
||||
points[numSpots].fMetric = MetricFunction(vNewSpawn, this, player);
|
||||
numSpots++;
|
||||
|
||||
if (numSpots >= (sizeof(points) / sizeof(points[0]))) {
|
||||
break;
|
||||
@@ -497,6 +495,7 @@ PlayerStart *DM_Team::GetRandomSpawnpointWithMetric(
|
||||
if (!SpotWouldTelefrag(spot->origin)) {
|
||||
points[numSpots].spawnpoint = spot;
|
||||
points[numSpots].fMetric = MetricFunction(spot->origin, this, player);
|
||||
numSpots++;
|
||||
|
||||
if (numSpots >= (sizeof(points) / sizeof(points[0]))) {
|
||||
break;
|
||||
@@ -677,6 +676,7 @@ DM_Manager::DM_Manager()
|
||||
m_bAllowAxisRespawn = true;
|
||||
m_bAllowAlliedRespawn = true;
|
||||
m_bRoundActive = false;
|
||||
m_iTotalMapTime = 0;
|
||||
}
|
||||
|
||||
DM_Manager::~DM_Manager() {}
|
||||
@@ -1245,7 +1245,7 @@ bool DM_Manager::CheckEndMatch()
|
||||
if (AllowRespawn() || (!m_team_axis.IsDead() && !m_team_allies.IsDead())) {
|
||||
int roundLimit = GetRoundLimit();
|
||||
|
||||
if (roundLimit > 0 && level.time >= m_iDefaultRoundLimit * 60 + m_fRoundTime) {
|
||||
if (roundLimit > 0 && level.time >= roundLimit * 60 + m_fRoundTime) {
|
||||
if (m_csTeamBombPlantSide != STRING_DRAW) {
|
||||
if (m_bIgnoringClockForBomb) {
|
||||
if (m_iNumBombsPlanted > 0) {
|
||||
@@ -1254,7 +1254,7 @@ bool DM_Manager::CheckEndMatch()
|
||||
|
||||
m_bIgnoringClockForBomb = false;
|
||||
} else if (m_iNumBombsPlanted > 0) {
|
||||
G_PrintToAllClients("A bomb is still set!");
|
||||
G_PrintToAllClients(va("%s\n", gi.LV_ConvertString("A Bomb is Still Set!")));
|
||||
m_bIgnoringClockForBomb = true;
|
||||
return false;
|
||||
}
|
||||
@@ -1328,7 +1328,7 @@ bool DM_Manager::CheckEndMatch()
|
||||
return true;
|
||||
} else if (m_iNumBombsPlanted >= m_iNumTargetsToDestroy - m_iNumTargetsDestroyed) {
|
||||
if (!m_bIgnoringClockForBomb) {
|
||||
G_PrintToAllClients("A bomb is still set!");
|
||||
G_PrintToAllClients(va("%s\n", gi.LV_ConvertString("A Bomb is Still Set!")));
|
||||
m_bIgnoringClockForBomb = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -847,7 +847,20 @@ void Door::DoorBlocked(Event *ev)
|
||||
|
||||
if (state == STATE_OPENING || state == STATE_OPEN) {
|
||||
spawnflags &= ~DOOR_START_OPEN;
|
||||
|
||||
const bool bIsMoving = EventPending(EV_MoveDone);
|
||||
ProcessEvent(EV_Door_Close);
|
||||
|
||||
if (bIsMoving) {
|
||||
// Added in OPM
|
||||
// Reopen to the other side so sentients can still pass.
|
||||
// This avoid entities like players trying to prevent the door
|
||||
// from opening in multiplayer
|
||||
diropened = -diropened;
|
||||
e = new Event(EV_Door_Open);
|
||||
e->AddEntity(other);
|
||||
ProcessEvent(e);
|
||||
}
|
||||
} else {
|
||||
e = new Event(EV_Door_Open);
|
||||
e->AddEntity(other);
|
||||
|
||||
@@ -2996,7 +2996,6 @@ void Entity::FadeIn(Event *ev)
|
||||
|
||||
if (ev->NumArgs() > 0) {
|
||||
rate = ev->GetFloat(1);
|
||||
assert(rate);
|
||||
if (rate > 0) {
|
||||
rate = FRAMETIME / rate;
|
||||
}
|
||||
@@ -3032,7 +3031,6 @@ void Entity::Fade(Event *ev)
|
||||
|
||||
if (ev->NumArgs() > 0) {
|
||||
rate = ev->GetFloat(1);
|
||||
assert(rate);
|
||||
if (rate > 0) {
|
||||
rate = FRAMETIME / rate;
|
||||
}
|
||||
@@ -5721,6 +5719,14 @@ void Entity::Delete(void)
|
||||
// Delete the entity the next frame
|
||||
|
||||
if (g_iInThinks) {
|
||||
if (ProcessingEvents) {
|
||||
// Fixed in OPM
|
||||
// Add a slight delay because otherwise this would cause an infinite loop
|
||||
// when processing pending events
|
||||
PostEvent(EV_Remove, 0.001);
|
||||
return;
|
||||
}
|
||||
|
||||
PostEvent(EV_Remove, 0);
|
||||
} else {
|
||||
delete this;
|
||||
|
||||
+36
-12
@@ -43,7 +43,7 @@ Return whether or not the specified filename is for allies
|
||||
*/
|
||||
bool IsAlliedPlayerModel(const char *filename)
|
||||
{
|
||||
return !Q_stricmpn(filename, "/allied_", 8) || !Q_stricmpn(filename, "/american_", 10);
|
||||
return !Q_stricmpn(filename, "allied_", 7) || !Q_stricmpn(filename, "american_", 9);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -55,7 +55,7 @@ Return whether or not the specified filename is for axis
|
||||
*/
|
||||
bool IsGermanPlayerModel(const char *filename)
|
||||
{
|
||||
return !Q_stricmpn(filename, "/german_", 8) || !Q_stricmpn(filename, "/IT_", 4) || !Q_stricmpn(filename, "/SC_", 4);
|
||||
return !Q_stricmpn(filename, "german_", 7) || !Q_stricmpn(filename, "IT_", 3) || !Q_stricmpn(filename, "SC_", 3);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -140,9 +140,9 @@ void InitModelList()
|
||||
}
|
||||
|
||||
if (IsAlliedPlayerModel(filename)) {
|
||||
alliedModelList.AddObject(str(filename + 1, 0, len - 5));
|
||||
alliedModelList.AddObject(str(filename, 0, len - 4));
|
||||
} else {
|
||||
germanModelList.AddObject(str(filename + 1, 0, len - 5));
|
||||
germanModelList.AddObject(str(filename, 0, len - 4));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,6 +383,36 @@ bool G_IsPlayer(gentity_t *ent)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_GetRandomAlliedPlayerModel
|
||||
============
|
||||
*/
|
||||
const char* G_GetRandomAlliedPlayerModel()
|
||||
{
|
||||
if (!alliedModelList.NumObjects()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const unsigned int index = rand() % alliedModelList.NumObjects();
|
||||
return alliedModelList[index];
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_GetRandomGermanPlayerModel
|
||||
============
|
||||
*/
|
||||
const char* G_GetRandomGermanPlayerModel()
|
||||
{
|
||||
if (!germanModelList.NumObjects()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const unsigned int index = rand() % germanModelList.NumObjects();
|
||||
return germanModelList[index];
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_AddBot
|
||||
@@ -429,14 +459,8 @@ void G_AddBot(const saved_bot_t *saved)
|
||||
//
|
||||
// Choose a random model
|
||||
//
|
||||
if (alliedModelList.NumObjects()) {
|
||||
const unsigned int index = rand() % alliedModelList.NumObjects();
|
||||
Info_SetValueForKey(userinfo, "dm_playermodel", alliedModelList[index]);
|
||||
}
|
||||
if (germanModelList.NumObjects()) {
|
||||
const unsigned int index = rand() % germanModelList.NumObjects();
|
||||
Info_SetValueForKey(userinfo, "dm_playergermanmodel", germanModelList[index]);
|
||||
}
|
||||
Info_SetValueForKey(userinfo, "dm_playermodel", G_GetRandomAlliedPlayerModel());
|
||||
Info_SetValueForKey(userinfo, "dm_playergermanmodel", G_GetRandomGermanPlayerModel());
|
||||
|
||||
Info_SetValueForKey(userinfo, "fov", "80");
|
||||
Info_SetValueForKey(userinfo, "ip", "localhost");
|
||||
|
||||
+3
-1
@@ -40,4 +40,6 @@ void G_ResetBots();
|
||||
void G_BotInit();
|
||||
void G_BotFrame();
|
||||
void G_BotPostInit();
|
||||
void G_SpawnBots();
|
||||
void G_SpawnBots();
|
||||
const char* G_GetRandomAlliedPlayerModel();
|
||||
const char* G_GetRandomGermanPlayerModel();
|
||||
@@ -772,7 +772,7 @@ void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
|
||||
|
||||
clientnum = ent - g_entities;
|
||||
|
||||
if (gi.SanitizeName(s, client->pers.netname)) {
|
||||
if (gi.SanitizeName(s, client->pers.netname, sizeof(client->pers.netname))) {
|
||||
gi.Printf("WARNING: had to sanitize the name for client %i\n", clientnum);
|
||||
}
|
||||
|
||||
@@ -794,7 +794,7 @@ void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
|
||||
|
||||
Q_strncpyz(client->pers.dm_playergermanmodel, s, sizeof(client->pers.dm_playergermanmodel));
|
||||
|
||||
gi.setConfigstring(CS_PLAYERS + clientnum, va("name\\%s", client->pers.netname));
|
||||
G_SetClientConfigString(ent);
|
||||
|
||||
if (ent->entity) {
|
||||
float fov;
|
||||
|
||||
+14
-16
@@ -1881,8 +1881,8 @@ void G_ExitLevel(void)
|
||||
// The nextmap cvar was set (possibly by a vote - so go ahead and use it)
|
||||
level.nextmap = sv_nextmap->string;
|
||||
gi.cvar_set("nextmap", "");
|
||||
} else // Use the next map in the maplist
|
||||
{
|
||||
} else {
|
||||
// Use the next map in the maplist
|
||||
char *s, *f, *t;
|
||||
|
||||
f = NULL;
|
||||
@@ -1892,19 +1892,17 @@ void G_ExitLevel(void)
|
||||
if (!Q_stricmp(t, level.mapname.c_str())) {
|
||||
// it's in the list, go to the next one
|
||||
t = strtok(NULL, seps);
|
||||
if (t == NULL) // end of list, go to first one
|
||||
{
|
||||
if (f == NULL) // there isn't a first one, same level
|
||||
{
|
||||
level.nextmap = level.mapname;
|
||||
} else {
|
||||
level.nextmap = f;
|
||||
}
|
||||
} else {
|
||||
if (t) {
|
||||
level.nextmap = t;
|
||||
} else if (f) {
|
||||
// end of list, go to first one
|
||||
level.nextmap = f;
|
||||
} else {
|
||||
// there isn't a first one, same level
|
||||
level.nextmap = level.mapname;
|
||||
}
|
||||
free(s);
|
||||
goto out;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// set the first map
|
||||
@@ -1915,7 +1913,7 @@ void G_ExitLevel(void)
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
out:
|
||||
|
||||
// level.nextmap should be set now, but if it isn't use the same map
|
||||
if (level.nextmap.length() == 0) {
|
||||
// Stay on the same map since no nextmap was set
|
||||
@@ -1929,8 +1927,8 @@ void G_ExitLevel(void)
|
||||
// alias on another map
|
||||
Q_strncpyz(command, level.nextmap, sizeof(command));
|
||||
gi.SendConsoleCommand(command);
|
||||
} else // use the level.nextmap variable
|
||||
{
|
||||
} else {
|
||||
// use the level.nextmap variable
|
||||
Com_sprintf(command, sizeof(command), "gamemap \"%s\"\n", level.nextmap.c_str());
|
||||
gi.SendConsoleCommand(command);
|
||||
}
|
||||
|
||||
+918
-1167
File diff suppressed because it is too large.
Load diff
+37
-40
@@ -29,52 +29,49 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
class Entity;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STEPMOVE_OK,
|
||||
STEPMOVE_BLOCKED_BY_ENTITY,
|
||||
STEPMOVE_BLOCKED_BY_WORLD,
|
||||
STEPMOVE_BLOCKED_BY_WATER,
|
||||
STEPMOVE_BLOCKED_BY_FALL,
|
||||
STEPMOVE_BLOCKED_BY_DOOR,
|
||||
STEPMOVE_STUCK
|
||||
typedef enum {
|
||||
STEPMOVE_OK,
|
||||
STEPMOVE_BLOCKED_BY_ENTITY,
|
||||
STEPMOVE_BLOCKED_BY_WORLD,
|
||||
STEPMOVE_BLOCKED_BY_WATER,
|
||||
STEPMOVE_BLOCKED_BY_FALL,
|
||||
STEPMOVE_BLOCKED_BY_DOOR,
|
||||
STEPMOVE_STUCK
|
||||
} stepmoveresult_t;
|
||||
|
||||
// movetype values
|
||||
typedef enum
|
||||
{
|
||||
MOVETYPE_NONE, // never moves
|
||||
MOVETYPE_STATIONARY, // never moves but does collide agains push objects
|
||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
||||
MOVETYPE_STOP, // no clip to world, stops on box contact
|
||||
MOVETYPE_WALK, // gravity
|
||||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, // gravity
|
||||
MOVETYPE_FLYMISSILE, // extra size to monsters
|
||||
MOVETYPE_BOUNCE,
|
||||
MOVETYPE_SLIDE,
|
||||
MOVETYPE_GIB,
|
||||
MOVETYPE_VEHICLE,
|
||||
MOVETYPE_TURRET,
|
||||
MOVETYPE_PORTABLE_TURRET
|
||||
typedef enum {
|
||||
MOVETYPE_NONE, // never moves
|
||||
MOVETYPE_STATIONARY, // never moves but does collide agains push objects
|
||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
||||
MOVETYPE_STOP, // no clip to world, stops on box contact
|
||||
MOVETYPE_WALK, // gravity
|
||||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, // gravity
|
||||
MOVETYPE_FLYMISSILE, // extra size to monsters
|
||||
MOVETYPE_BOUNCE,
|
||||
MOVETYPE_SLIDE,
|
||||
MOVETYPE_GIB,
|
||||
MOVETYPE_VEHICLE,
|
||||
MOVETYPE_TURRET,
|
||||
MOVETYPE_PORTABLE_TURRET
|
||||
} movetype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Entity *ent;
|
||||
Vector localorigin;
|
||||
Vector origin;
|
||||
Vector localangles;
|
||||
Vector angles;
|
||||
float deltayaw;
|
||||
typedef struct {
|
||||
Entity *ent;
|
||||
Vector localorigin;
|
||||
Vector origin;
|
||||
Vector localangles;
|
||||
Vector angles;
|
||||
float deltayaw;
|
||||
} pushed_t;
|
||||
|
||||
extern pushed_t pushed[];
|
||||
extern pushed_t pushed[];
|
||||
extern pushed_t *pushed_p;
|
||||
|
||||
void G_RunEntity( Entity *ent );
|
||||
void G_Impact( Entity *e1, trace_t *trace );
|
||||
qboolean G_PushMove( Entity *pusher, Vector move, Vector amove );
|
||||
void G_CheckWater( Entity *ent );
|
||||
Entity *G_TestEntityPosition( Entity *ent, Vector vOrg );
|
||||
void G_RunEntity(Entity *ent);
|
||||
void G_Impact(Entity *e1, trace_t *trace);
|
||||
qboolean G_PushMove(Entity *pusher, Vector move, Vector amove);
|
||||
void G_CheckWater(Entity *ent);
|
||||
Entity *G_TestEntityPosition(Entity *ent, Vector vOrg);
|
||||
@@ -478,7 +478,7 @@ typedef struct gameImport_s {
|
||||
void (*HudDrawAlpha)(int info, float alpha);
|
||||
void (*HudDrawString)(int info, const char *string);
|
||||
void (*HudDrawFont)(int info, const char *fontName);
|
||||
qboolean (*SanitizeName)(const char *oldName, char *newName);
|
||||
qboolean (*SanitizeName)(const char *oldName, char *newName, size_t bufferSize);
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
|
||||
@@ -87,6 +87,13 @@ Called on a first-time connect
|
||||
*/
|
||||
void G_InitClientPersistant( gclient_t *client, const char *userinfo )
|
||||
{
|
||||
// Clear the persistent data
|
||||
client->pers = {};
|
||||
|
||||
// Added in OPM
|
||||
// Reset the persistent session data.
|
||||
// This fixes some bugs like the player getting score
|
||||
// from previous maps
|
||||
G_WriteClientSessionData( client );
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -924,10 +924,10 @@ float G_GetAngle(Vector movedir)
|
||||
angle = RAD2DEG(atan(1.0) * 2 + atan(-movedir[0] / sqrt(-movedir[0] * movedir[0] + 1.0)));
|
||||
|
||||
if (movedir[1] < 0) {
|
||||
return 360 - angle;
|
||||
return (int)((360 - angle) * 10000) / 10000.0;
|
||||
}
|
||||
|
||||
return angle;
|
||||
return (int)(angle * 10000) / 10000.0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2171,9 +2171,9 @@ void G_PrintToAllClients(const char *pszString, int iType)
|
||||
}
|
||||
} else {
|
||||
if (iType == 0) {
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_YELLOW "%s\n\"", pszString);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_YELLOW "%s\"", pszString);
|
||||
} else {
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_WHITE "%s\n\"", pszString);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_WHITE "%s\"", pszString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2232,9 +2232,12 @@ G_PrintDeathMessageEmulated(const char *s1, const char *s2, char *attackerName,
|
||||
result2 = NULL;
|
||||
|
||||
if (type == tolower(type)) {
|
||||
// Enemy
|
||||
hudColor = 4;
|
||||
} else {
|
||||
hudColor = 5;
|
||||
// Friend
|
||||
//hudColor = 5;
|
||||
hudColor = 4;
|
||||
}
|
||||
|
||||
if (*s1 != 'x') {
|
||||
@@ -2327,7 +2330,7 @@ void G_PrintDeathMessage_Old(const char *pszString)
|
||||
continue;
|
||||
}
|
||||
|
||||
gi.SendServerCommand(ent - g_entities, "print \"" HUD_MESSAGE_CHAT_RED "%s\"", pszString);
|
||||
gi.SendServerCommand(ent - g_entities, "print \"%s\"", pszString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2449,3 +2452,7 @@ gentity_t *G_GetGEntity(int ent_num)
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
unsigned int G_GetWeaponCommand(unsigned int buttons) {
|
||||
return GetWeaponCommand(buttons, g_protocol >= PROTOCOL_MOHTA_MIN ? WEAPON_COMMAND_MAX_VER17 : WEAPON_COMMAND_MAX_VER6);
|
||||
}
|
||||
@@ -327,3 +327,4 @@ const char *WeaponHandNumToName(weaponhand_t hand);
|
||||
weaponhand_t WeaponHandNameToNum(str side);
|
||||
void G_DebugTargets(Entity *e, str from);
|
||||
void G_DebugDamage(float damage, Entity *victim, Entity *attacker, Entity *inflictor);
|
||||
unsigned int G_GetWeaponCommand(unsigned int buttons);
|
||||
+4
-8
@@ -418,15 +418,11 @@ void Item::RemoveFromOwner(void)
|
||||
|
||||
void Item::Delete(void)
|
||||
{
|
||||
if (g_iInThinks) {
|
||||
if (owner) {
|
||||
RemoveFromOwner();
|
||||
}
|
||||
|
||||
PostEvent(EV_Remove, 0);
|
||||
} else {
|
||||
delete this;
|
||||
if (g_iInThinks && owner) {
|
||||
RemoveFromOwner();
|
||||
}
|
||||
|
||||
Animate::Delete();
|
||||
}
|
||||
|
||||
void Item::SetNoRemove(Event *ev)
|
||||
|
||||
@@ -969,8 +969,8 @@ void Level::CleanUp(qboolean samemap, qboolean resetConfigStrings)
|
||||
gi.setConfigstring(CS_RAIN_NUMSHADERS, "0");
|
||||
gi.setConfigstring(CS_CURRENT_OBJECTIVE, "");
|
||||
|
||||
for (int i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; i++) {
|
||||
gi.setConfigstring(i, "");
|
||||
for (i = 0; i < MAX_OBJECTIVES; i++) {
|
||||
gi.setConfigstring(CS_OBJECTIVES + i, "");
|
||||
}
|
||||
|
||||
gi.setConfigstring(CS_VOTE_TIME, "");
|
||||
@@ -1097,6 +1097,12 @@ void Level::SpawnEntities(char *entities, int svsTime)
|
||||
int start, end;
|
||||
char name[128];
|
||||
|
||||
if (gi.Cvar_Get("g_invulnoverride", "0", 0)->integer == 1) {
|
||||
// Added in 2.30
|
||||
// Clear the invulnerable override when loading
|
||||
gi.cvar_set("g_invulnoverride", "0");
|
||||
}
|
||||
|
||||
Com_Printf("-------------------- Spawning Entities -----------------------\n");
|
||||
|
||||
t1 = gi.Milliseconds();
|
||||
|
||||
+1
-1
@@ -3094,7 +3094,7 @@ void FuncLadder::AdjustPositionOnLadder(Entity *pUser)
|
||||
);
|
||||
}
|
||||
|
||||
pUser->setOrigin(trace.endpos + m_vFacingDir * 0.005);
|
||||
pUser->setOrigin(trace.endpos);
|
||||
}
|
||||
|
||||
void FuncLadder::EnsureOverLadder(Entity *pUser)
|
||||
|
||||
+156
-190
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -35,93 +35,81 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#define MOVE_ANGLES 1
|
||||
#define MOVE_ORIGIN 2
|
||||
|
||||
CLASS_DECLARATION( Trigger, Mover, "mover" )
|
||||
{
|
||||
{ &EV_MoveDone, &Mover::MoveDone },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
CLASS_DECLARATION(Trigger, Mover, "mover") {
|
||||
{&EV_MoveDone, &Mover::MoveDone},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
Mover::Mover()
|
||||
{
|
||||
endevent = NULL;
|
||||
}
|
||||
|
||||
Mover::~Mover()
|
||||
{
|
||||
}
|
||||
|
||||
void Mover::MoveDone
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
{
|
||||
Event * event;
|
||||
Vector move;
|
||||
Vector amove;
|
||||
endevent = NULL;
|
||||
}
|
||||
|
||||
// zero out the movement
|
||||
Mover::~Mover() {}
|
||||
|
||||
void Mover::MoveDone(Event *ev)
|
||||
{
|
||||
Event *event;
|
||||
Vector move;
|
||||
Vector amove;
|
||||
|
||||
// zero out the movement
|
||||
avelocity = vec_zero;
|
||||
if( moveflags & MOVE_ANGLES )
|
||||
{
|
||||
amove = angledest - localangles;
|
||||
}
|
||||
else
|
||||
{
|
||||
amove = vec_zero;
|
||||
}
|
||||
if (moveflags & MOVE_ANGLES) {
|
||||
amove = angledest - localangles;
|
||||
} else {
|
||||
amove = vec_zero;
|
||||
}
|
||||
|
||||
velocity = vec_zero;
|
||||
if( moveflags & MOVE_ORIGIN )
|
||||
{
|
||||
move = finaldest - localorigin;
|
||||
}
|
||||
else
|
||||
{
|
||||
move = vec_zero;
|
||||
}
|
||||
if (moveflags & MOVE_ORIGIN) {
|
||||
move = finaldest - localorigin;
|
||||
} else {
|
||||
move = vec_zero;
|
||||
}
|
||||
|
||||
accel = vec_zero;
|
||||
accel = vec_zero;
|
||||
aaccel = vec_zero;
|
||||
|
||||
if( !G_PushMove( this, move, amove ) )
|
||||
{
|
||||
// Delay finish till we can move into the final position
|
||||
PostEvent( EV_MoveDone, FRAMETIME );
|
||||
return;
|
||||
}
|
||||
if (!G_PushMove(this, move, amove)) {
|
||||
// Added in OPM
|
||||
// Check to make sure the event isn't pending
|
||||
// blocked events called by G_PushMove() might alter
|
||||
// the mover
|
||||
if (!EventPending(EV_MoveDone)) {
|
||||
// Delay finish till we can move into the final position
|
||||
PostEvent(EV_MoveDone, FRAMETIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// After moving, set origin to exact final destination
|
||||
//
|
||||
if( moveflags & MOVE_ORIGIN )
|
||||
{
|
||||
setLocalOrigin( finaldest );
|
||||
}
|
||||
//
|
||||
// After moving, set origin to exact final destination
|
||||
//
|
||||
if (moveflags & MOVE_ORIGIN) {
|
||||
setLocalOrigin(finaldest);
|
||||
}
|
||||
|
||||
if( moveflags & MOVE_ANGLES )
|
||||
{
|
||||
localangles = angledest;
|
||||
if (moveflags & MOVE_ANGLES) {
|
||||
localangles = angledest;
|
||||
|
||||
if( ( localangles.x >= 360 ) || ( localangles.x < 0 ) )
|
||||
{
|
||||
localangles.x -= ( ( int )localangles.x / 360 ) * 360;
|
||||
}
|
||||
if( ( localangles.y >= 360 ) || ( localangles.y < 0 ) )
|
||||
{
|
||||
localangles.y -= ( ( int )localangles.y / 360 ) * 360;
|
||||
}
|
||||
if( ( localangles.z >= 360 ) || ( localangles.z < 0 ) )
|
||||
{
|
||||
localangles.z -= ( ( int )localangles.z / 360 ) * 360;
|
||||
}
|
||||
}
|
||||
if ((localangles.x >= 360) || (localangles.x < 0)) {
|
||||
localangles.x -= ((int)localangles.x / 360) * 360;
|
||||
}
|
||||
if ((localangles.y >= 360) || (localangles.y < 0)) {
|
||||
localangles.y -= ((int)localangles.y / 360) * 360;
|
||||
}
|
||||
if ((localangles.z >= 360) || (localangles.z < 0)) {
|
||||
localangles.z -= ((int)localangles.z / 360) * 360;
|
||||
}
|
||||
}
|
||||
|
||||
event = endevent;
|
||||
endevent = NULL;
|
||||
event = endevent;
|
||||
endevent = NULL;
|
||||
|
||||
if( event )
|
||||
ProcessEvent( event );
|
||||
if (event) {
|
||||
ProcessEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -132,99 +120,87 @@ calculate self.velocity and self.nextthink to reach dest from
|
||||
self.origin traveling at speed
|
||||
===============
|
||||
*/
|
||||
void Mover::MoveTo( Vector tdest, Vector angdest, float tspeed, Event& event )
|
||||
void Mover::MoveTo(Vector tdest, Vector angdest, float tspeed, Event& event)
|
||||
{
|
||||
Vector vdestdelta;
|
||||
Vector angdestdelta;
|
||||
float len;
|
||||
float traveltime;
|
||||
Vector vdestdelta;
|
||||
Vector angdestdelta;
|
||||
float len;
|
||||
float traveltime;
|
||||
|
||||
assert( tspeed >= 0.0f );
|
||||
assert(tspeed >= 0.0f);
|
||||
|
||||
if( !tspeed )
|
||||
{
|
||||
error( "MoveTo", "No speed is defined!" );
|
||||
}
|
||||
if (!tspeed) {
|
||||
error("MoveTo", "No speed is defined!");
|
||||
}
|
||||
|
||||
if( tspeed < 0.0f )
|
||||
{
|
||||
error( "MoveTo", "Speed is negative!" );
|
||||
}
|
||||
if (tspeed < 0.0f) {
|
||||
error("MoveTo", "Speed is negative!");
|
||||
}
|
||||
|
||||
// Cancel previous moves
|
||||
CancelEventsOfType( EV_MoveDone );
|
||||
// Cancel previous moves
|
||||
CancelEventsOfType(EV_MoveDone);
|
||||
|
||||
moveflags = 0;
|
||||
moveflags = 0;
|
||||
|
||||
if( endevent )
|
||||
{
|
||||
delete endevent;
|
||||
}
|
||||
if (endevent) {
|
||||
delete endevent;
|
||||
}
|
||||
|
||||
endevent = new Event( event );
|
||||
endevent = new Event(event);
|
||||
|
||||
finaldest = tdest;
|
||||
angledest = angdest;
|
||||
finaldest = tdest;
|
||||
angledest = angdest;
|
||||
|
||||
if( finaldest != localorigin )
|
||||
{
|
||||
moveflags |= MOVE_ORIGIN;
|
||||
}
|
||||
if( angledest != localangles )
|
||||
{
|
||||
moveflags |= MOVE_ANGLES;
|
||||
}
|
||||
if (finaldest != localorigin) {
|
||||
moveflags |= MOVE_ORIGIN;
|
||||
}
|
||||
if (angledest != localangles) {
|
||||
moveflags |= MOVE_ANGLES;
|
||||
}
|
||||
|
||||
if( !moveflags )
|
||||
{
|
||||
// stop the object from moving
|
||||
velocity = vec_zero;
|
||||
avelocity = vec_zero;
|
||||
if (!moveflags) {
|
||||
// stop the object from moving
|
||||
velocity = vec_zero;
|
||||
avelocity = vec_zero;
|
||||
|
||||
// post the event so we don't wait forever
|
||||
PostEvent( EV_MoveDone, FRAMETIME );
|
||||
return;
|
||||
}
|
||||
// post the event so we don't wait forever
|
||||
PostEvent(EV_MoveDone, FRAMETIME);
|
||||
return;
|
||||
}
|
||||
|
||||
// set destdelta to the vector needed to move
|
||||
vdestdelta = tdest - localorigin;
|
||||
angdestdelta[ 0 ] = angledist( angdest[ 0 ] - localangles[ 0 ] );
|
||||
angdestdelta[ 1 ] = angledist( angdest[ 1 ] - localangles[ 1 ] );
|
||||
angdestdelta[ 2 ] = angledist( angdest[ 2 ] - localangles[ 2 ] );
|
||||
// set destdelta to the vector needed to move
|
||||
vdestdelta = tdest - localorigin;
|
||||
angdestdelta[0] = angledist(angdest[0] - localangles[0]);
|
||||
angdestdelta[1] = angledist(angdest[1] - localangles[1]);
|
||||
angdestdelta[2] = angledist(angdest[2] - localangles[2]);
|
||||
|
||||
if( tdest == localorigin )
|
||||
{
|
||||
// calculate length of vector based on angles
|
||||
len = angdestdelta.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate length of vector based on distance
|
||||
len = vdestdelta.length();
|
||||
}
|
||||
if (tdest == localorigin) {
|
||||
// calculate length of vector based on angles
|
||||
len = angdestdelta.length();
|
||||
} else {
|
||||
// calculate length of vector based on distance
|
||||
len = vdestdelta.length();
|
||||
}
|
||||
|
||||
// divide by speed to get time to reach dest
|
||||
traveltime = len / tspeed;
|
||||
// divide by speed to get time to reach dest
|
||||
traveltime = len / tspeed;
|
||||
|
||||
if( traveltime < level.frametime )
|
||||
{
|
||||
traveltime = level.frametime;
|
||||
vdestdelta = vec_zero;
|
||||
angdestdelta = vec_zero;
|
||||
}
|
||||
if (traveltime < level.frametime) {
|
||||
traveltime = level.frametime;
|
||||
vdestdelta = vec_zero;
|
||||
angdestdelta = vec_zero;
|
||||
}
|
||||
|
||||
// scale the destdelta vector by the time spent traveling to get velocity
|
||||
if( moveflags & MOVE_ORIGIN )
|
||||
{
|
||||
velocity = vdestdelta * ( 1.0f / traveltime );
|
||||
}
|
||||
// scale the destdelta vector by the time spent traveling to get velocity
|
||||
if (moveflags & MOVE_ORIGIN) {
|
||||
velocity = vdestdelta * (1.0f / traveltime);
|
||||
}
|
||||
|
||||
if( moveflags & MOVE_ANGLES )
|
||||
{
|
||||
avelocity = angdestdelta * ( 1.0f / traveltime );
|
||||
}
|
||||
if (moveflags & MOVE_ANGLES) {
|
||||
avelocity = angdestdelta * (1.0f / traveltime);
|
||||
}
|
||||
|
||||
PostEvent( EV_MoveDone, traveltime );
|
||||
PostEvent(EV_MoveDone, traveltime);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -232,55 +208,45 @@ void Mover::MoveTo( Vector tdest, Vector angdest, float tspeed, Event& event )
|
||||
LinearInterpolate
|
||||
===============
|
||||
*/
|
||||
void Mover::LinearInterpolate
|
||||
(
|
||||
Vector tdest,
|
||||
Vector angdest,
|
||||
float time,
|
||||
Event &event
|
||||
)
|
||||
void Mover::LinearInterpolate(Vector tdest, Vector angdest, float time, Event& event)
|
||||
{
|
||||
Vector vdestdelta;
|
||||
Vector angdestdelta;
|
||||
float t;
|
||||
Vector vdestdelta;
|
||||
Vector angdestdelta;
|
||||
float t;
|
||||
|
||||
if( endevent )
|
||||
{
|
||||
delete endevent;
|
||||
}
|
||||
endevent = new Event( event );
|
||||
finaldest = tdest;
|
||||
angledest = angdest;
|
||||
if (endevent) {
|
||||
delete endevent;
|
||||
}
|
||||
endevent = new Event(event);
|
||||
finaldest = tdest;
|
||||
angledest = angdest;
|
||||
|
||||
// Cancel previous moves
|
||||
CancelEventsOfType( EV_MoveDone );
|
||||
// Cancel previous moves
|
||||
CancelEventsOfType(EV_MoveDone);
|
||||
|
||||
// Quantize to FRAMETIME
|
||||
if( time < FRAMETIME )
|
||||
{
|
||||
time = FRAMETIME;
|
||||
}
|
||||
// Quantize to FRAMETIME
|
||||
if (time < FRAMETIME) {
|
||||
time = FRAMETIME;
|
||||
}
|
||||
|
||||
moveflags = 0;
|
||||
t = 1 / time;
|
||||
// scale the destdelta vector by the time spent traveling to get velocity
|
||||
if( finaldest != localorigin )
|
||||
{
|
||||
vdestdelta = tdest - localorigin;
|
||||
velocity = vdestdelta * t;
|
||||
moveflags |= MOVE_ORIGIN;
|
||||
}
|
||||
moveflags = 0;
|
||||
t = 1 / time;
|
||||
// scale the destdelta vector by the time spent traveling to get velocity
|
||||
if (finaldest != localorigin) {
|
||||
vdestdelta = tdest - localorigin;
|
||||
velocity = vdestdelta * t;
|
||||
moveflags |= MOVE_ORIGIN;
|
||||
}
|
||||
|
||||
if( angledest != localangles )
|
||||
{
|
||||
angdestdelta = angdest - localangles;
|
||||
avelocity = angdestdelta * t;
|
||||
moveflags |= MOVE_ANGLES;
|
||||
}
|
||||
if (angledest != localangles) {
|
||||
angdestdelta = angdest - localangles;
|
||||
avelocity = angdestdelta * t;
|
||||
moveflags |= MOVE_ANGLES;
|
||||
}
|
||||
|
||||
if( g_bBeforeThinks )
|
||||
time -= FRAMETIME;
|
||||
if (g_bBeforeThinks) {
|
||||
time -= FRAMETIME;
|
||||
}
|
||||
|
||||
PostEvent( EV_MoveDone, time );
|
||||
PostEvent(EV_MoveDone, time);
|
||||
}
|
||||
|
||||
+24
-27
@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// Base class for any object that needs to move to specific locations over a
|
||||
// period of time. This class is kept separate from most entities to keep
|
||||
// class size down for objects that don't need such behavior.
|
||||
//
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -33,33 +33,30 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "trigger.h"
|
||||
|
||||
class Mover : public Trigger
|
||||
{
|
||||
private:
|
||||
Vector finaldest;
|
||||
Vector angledest;
|
||||
Event *endevent;
|
||||
int moveflags;
|
||||
{
|
||||
private:
|
||||
Vector finaldest;
|
||||
Vector angledest;
|
||||
Event *endevent;
|
||||
int moveflags;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( Mover );
|
||||
public:
|
||||
CLASS_PROTOTYPE(Mover);
|
||||
|
||||
Mover();
|
||||
virtual ~Mover();
|
||||
void MoveDone( Event *ev );
|
||||
void MoveTo( Vector tdest, Vector angdest, float tspeed, Event &event );
|
||||
void LinearInterpolate( Vector tdest, Vector angdest, float time, Event &event );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
Mover();
|
||||
virtual ~Mover();
|
||||
void MoveDone(Event *ev);
|
||||
void MoveTo(Vector tdest, Vector angdest, float tspeed, Event& event);
|
||||
void LinearInterpolate(Vector tdest, Vector angdest, float time, Event& event);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void Mover::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
{
|
||||
Trigger::Archive( arc );
|
||||
inline void Mover::Archive(Archiver& arc)
|
||||
{
|
||||
Trigger::Archive(arc);
|
||||
|
||||
arc.ArchiveVector( &finaldest );
|
||||
arc.ArchiveVector( &angledest );
|
||||
arc.ArchiveEventPointer( &endevent );
|
||||
arc.ArchiveInteger( &moveflags );
|
||||
}
|
||||
arc.ArchiveVector(&finaldest);
|
||||
arc.ArchiveVector(&angledest);
|
||||
arc.ArchiveEventPointer(&endevent);
|
||||
arc.ArchiveInteger(&moveflags);
|
||||
}
|
||||
+49
-14
@@ -2413,6 +2413,12 @@ void Player::InitHealth(void)
|
||||
//
|
||||
m_fHealRate = 0;
|
||||
edict->s.eFlags &= ~EF_DEAD;
|
||||
|
||||
// Fixed in OPM
|
||||
// This avoid losing weapons when dying and then immediately respawning
|
||||
CancelEventsOfType(EV_Player_DMDeathDrop);
|
||||
// And this prevents the player from dying when respawning immediately after getting killed
|
||||
CancelEventsOfType(EV_Player_Dead);
|
||||
}
|
||||
|
||||
void Player::InitModel(void)
|
||||
@@ -4057,9 +4063,9 @@ void Player::ClientMove(usercmd_t *ucmd)
|
||||
// Also use the weapon movement speed
|
||||
//
|
||||
if (!IsZoomed()) {
|
||||
client->ps.speed = (float)client->ps.speed * pWeap->m_fMovementSpeed;
|
||||
client->ps.speed = (float)client->ps.speed * pWeap->GetMovementSpeed();
|
||||
} else {
|
||||
client->ps.speed = (float)client->ps.speed * pWeap->m_fZoomMovement * pWeap->m_fMovementSpeed;
|
||||
client->ps.speed = (float)client->ps.speed * pWeap->GetZoomMovement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4250,7 +4256,7 @@ void Player::ClientInactivityTimer(void)
|
||||
//
|
||||
// The player reached maximum team kills
|
||||
//
|
||||
G_PrintToAllClients(va("%s %s", client->pers.netname, message.c_str()), qfalse);
|
||||
G_PrintToAllClients(va("%s %s\n", client->pers.netname, message.c_str()), 2);
|
||||
|
||||
if (Q_stricmp(Info_ValueForKey(client->pers.userinfo, "ip"), "localhost")) {
|
||||
//
|
||||
@@ -4742,7 +4748,7 @@ void Player::Think(void)
|
||||
}
|
||||
} else {
|
||||
if ((server_new_buttons & BUTTON_USE)) {
|
||||
SetPlayerSpectateRandom();
|
||||
SetPlayerSpectate(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4801,7 +4807,7 @@ void Player::Think(void)
|
||||
}
|
||||
|
||||
if (!IsDead()) {
|
||||
m_iClientWeaponCommand = (server_new_buttons & WEAPON_COMMAND_MASK) >> 7;
|
||||
m_iClientWeaponCommand = G_GetWeaponCommand(server_new_buttons);
|
||||
|
||||
switch (m_iClientWeaponCommand) {
|
||||
case 0:
|
||||
@@ -7279,7 +7285,7 @@ void Player::UpdateStats(void)
|
||||
|
||||
trace = G_Trace(m_vViewPos, vec_zero, vec_zero, vEnd, this, MASK_BEAM, qfalse, "infoclientcheck");
|
||||
|
||||
if (trace.ent && trace.ent->entity->IsSubclassOfPlayer()) {
|
||||
if (trace.ent && trace.ent->entity->IsSubclassOfPlayer() && !(trace.ent->r.svFlags & SVF_NOCLIENT)) {
|
||||
Player *p = static_cast<Player *>(trace.ent->entity);
|
||||
|
||||
if (IsSpectator() || p->GetTeam() == GetTeam()) {
|
||||
@@ -10777,10 +10783,29 @@ void Player::EventDMMessage(Event *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//=============
|
||||
// Print the dm message to console
|
||||
sToken = "";
|
||||
|
||||
for (i = 2; i <= ev->NumArgs(); i++) {
|
||||
if (i != 2) {
|
||||
sToken += " ";
|
||||
}
|
||||
|
||||
sToken += ev->GetString(i);
|
||||
}
|
||||
//=============
|
||||
|
||||
if (iMode == 0) {
|
||||
//
|
||||
// everyone
|
||||
//
|
||||
|
||||
// Added in OPM
|
||||
gi.Printf("%s (%zu) says to everyone: %s\n", client->pers.netname, edict - g_entities, sToken.c_str());
|
||||
|
||||
if (!IsSpectator() || g_spectate_allow_full_chat->integer) {
|
||||
for (i = 0; i < game.maxclients; i++) {
|
||||
ent = &g_entities[i];
|
||||
@@ -10825,6 +10850,10 @@ void Player::EventDMMessage(Event *ev)
|
||||
//
|
||||
// team message
|
||||
//
|
||||
|
||||
// Added in OPM
|
||||
gi.Printf("%s (%zu) says to team: %s\n", client->pers.netname, edict - g_entities, sToken.c_str());
|
||||
|
||||
if (IsSpectator()) {
|
||||
for (i = 0; i < game.maxclients; i++) {
|
||||
ent = &g_entities[i];
|
||||
@@ -10884,6 +10913,9 @@ void Player::EventDMMessage(Event *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
// Added in OPM
|
||||
gi.Printf("%s (%zu) says to client #%d: %s\n", client->pers.netname, edict - g_entities, iMode - 1, sToken.c_str());
|
||||
|
||||
gi.SendServerCommand(iMode - 1, "%s", szPrintString);
|
||||
|
||||
if (ent->entity != this) {
|
||||
@@ -11195,17 +11227,17 @@ str Player::TranslateBattleLanguageTokens(const char *string)
|
||||
|
||||
void Player::EventIPrint(Event *ev)
|
||||
{
|
||||
str sString = ev->GetString(1);
|
||||
qboolean iBold = qfalse;
|
||||
str sString = ev->GetString(1);
|
||||
qboolean iBold = qfalse;
|
||||
|
||||
if (ev->NumArgs() > 1) {
|
||||
iBold = ev->GetInteger(2);
|
||||
}
|
||||
|
||||
if (iBold) {
|
||||
gi.SendServerCommand(edict - g_entities, "print \"" HUD_MESSAGE_WHITE "%s\n\"", sString.c_str());
|
||||
gi.SendServerCommand(edict - g_entities, "print \"" HUD_MESSAGE_WHITE "%s\n\"", gi.LV_ConvertString(sString.c_str()));
|
||||
} else {
|
||||
gi.SendServerCommand(edict - g_entities, "print \"" HUD_MESSAGE_YELLOW "%s\n\"", sString.c_str());
|
||||
gi.SendServerCommand(edict - g_entities, "print \"" HUD_MESSAGE_YELLOW "%s\n\"", gi.LV_ConvertString(sString.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11681,6 +11713,13 @@ void Player::FireWeapon(int number, firemode_t mode)
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_GetWeaponCommand(last_ucmd.buttons)) {
|
||||
// Added in OPM
|
||||
// If there is a weapon command (like DROP), then just don't fire
|
||||
// this prevent tricky behaviors, like silent firing
|
||||
return;
|
||||
}
|
||||
|
||||
Sentient::FireWeapon(number, mode);
|
||||
|
||||
if (g_gametype->integer != GT_SINGLE_PLAYER) {
|
||||
@@ -11986,10 +12025,6 @@ void Player::Spawned(void)
|
||||
void Player::AddKills(int num)
|
||||
{
|
||||
num_kills += num;
|
||||
|
||||
if (g_gametype->integer >= GT_TEAM_ROUNDS) {
|
||||
num_deaths += num;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::AddDeaths(int num)
|
||||
|
||||
@@ -345,18 +345,12 @@ void Player::AdjustAnimBlends(void)
|
||||
if (m_fPartBlends[legs] <= 0.0f) {
|
||||
if (partOldAnim[legs] != "") {
|
||||
StopAnimating(iOldPartSlot);
|
||||
}
|
||||
|
||||
if (partAnim[legs] == "") {
|
||||
SetWeight(iPartSlot, 0.0);
|
||||
} else {
|
||||
SetWeight(iPartSlot, 1.0);
|
||||
}
|
||||
if (partAnim[legs] == "") {
|
||||
SetWeight(iPartSlot, 0.0);
|
||||
} else {
|
||||
if (partAnim[legs] == "") {
|
||||
SetWeight(iPartSlot, 0.0);
|
||||
} else {
|
||||
SetWeight(iPartSlot, 1.0);
|
||||
}
|
||||
SetWeight(iPartSlot, 1.0);
|
||||
}
|
||||
} else {
|
||||
m_fPartBlends[legs] -= level.frametime * partBlendMult[legs];
|
||||
@@ -387,12 +381,14 @@ void Player::AdjustAnimBlends(void)
|
||||
if (partOldAnim[torso] != "") {
|
||||
StopAnimating(iOldPartSlot);
|
||||
partOldAnim[torso] = "";
|
||||
}
|
||||
|
||||
if (partAnim[torso] == "") {
|
||||
SetWeight(iPartSlot, 0.0);
|
||||
} else {
|
||||
SetWeight(iPartSlot, 1.0);
|
||||
}
|
||||
if (partAnim[torso] == "") {
|
||||
SetWeight(iPartSlot, 0.0);
|
||||
edict->s.actionWeight = 0.0;
|
||||
} else {
|
||||
SetWeight(iPartSlot, 1.0);
|
||||
edict->s.actionWeight = 1.0;
|
||||
}
|
||||
} else {
|
||||
m_fPartBlends[torso] = m_fPartBlends[torso] - level.frametime * partBlendMult[torso];
|
||||
@@ -427,16 +423,16 @@ void Player::AdjustAnimBlends(void)
|
||||
if (m_fPainBlend) {
|
||||
if (m_sPainAnim == "") {
|
||||
StopAnimating(ANIMSLOT_PAIN);
|
||||
edict->s.frameInfo[ANIMSLOT_PAIN].weight = 0;
|
||||
m_fPainBlend = 0;
|
||||
animdone_Pain = false;
|
||||
SetWeight(ANIMSLOT_PAIN, 0);
|
||||
m_fPainBlend = 0;
|
||||
animdone_Pain = false;
|
||||
} else if (animdone_Pain) {
|
||||
m_fPainBlend -= level.frametime * (10.0 / 3.0);
|
||||
if (m_fPainBlend < 0.01f) {
|
||||
StopAnimating(ANIMSLOT_PAIN);
|
||||
edict->s.frameInfo[ANIMSLOT_PAIN].weight = 0;
|
||||
m_fPainBlend = 0;
|
||||
animdone_Pain = false;
|
||||
SetWeight(ANIMSLOT_PAIN, 0);
|
||||
m_fPainBlend = 0;
|
||||
animdone_Pain = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,12 +440,12 @@ void Player::AdjustAnimBlends(void)
|
||||
int i;
|
||||
float w;
|
||||
|
||||
edict->s.frameInfo[ANIMSLOT_PAIN].weight = m_fPainBlend;
|
||||
w = 1.0 - m_fPainBlend * 0.5;
|
||||
SetWeight(ANIMSLOT_PAIN, m_fPainBlend);
|
||||
w = 1.0 - m_fPainBlend * 0.5;
|
||||
|
||||
for (i = 0; i < ANIMSLOT_PAIN; i++) {
|
||||
if (edict->s.frameInfo[i].weight) {
|
||||
edict->s.frameInfo[i].weight *= w;
|
||||
if (GetWeight(i)) {
|
||||
SetWeight(i, GetWeight(i) * w);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +486,7 @@ void Player::PlayerAnimDelta(float *vDelta)
|
||||
// get the anim delta
|
||||
gi.Anim_DeltaOverTime(edict->tiki, animnum, fBackTime, fTime, vNewDelta);
|
||||
|
||||
VectorMA(vDelta, edict->s.frameInfo[m_iPartSlot[legs]].weight, vNewDelta, vDelta);
|
||||
VectorMA(vDelta, GetWeight(m_iPartSlot[legs]), vNewDelta, vDelta);
|
||||
}
|
||||
|
||||
animnum = -1;
|
||||
@@ -509,15 +505,15 @@ void Player::PlayerAnimDelta(float *vDelta)
|
||||
|
||||
gi.Anim_DeltaOverTime(edict->tiki, animnum, fBackTime, fTime, vNewDelta);
|
||||
|
||||
VectorMA(vDelta, edict->s.frameInfo[m_iPartSlot[torso]].weight, vNewDelta, vDelta);
|
||||
VectorMA(vDelta, GetWeight(m_iPartSlot[torso]), vNewDelta, vDelta);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::EventTestAnim(Event *ev)
|
||||
{
|
||||
str name;
|
||||
str name;
|
||||
float weight;
|
||||
int animNum;
|
||||
int animNum;
|
||||
|
||||
weight = ev->GetFloat(1);
|
||||
if (weight <= 0) {
|
||||
@@ -527,7 +523,7 @@ void Player::EventTestAnim(Event *ev)
|
||||
}
|
||||
|
||||
if (ev->NumArgs() > 1) {
|
||||
name = ev->GetString(1);
|
||||
name = ev->GetString(1);
|
||||
animNum = gi.Anim_NumForName(edict->tiki, name.c_str());
|
||||
if (animNum == -1) {
|
||||
gi.Printf("Couldn't find anim '%s'\n", name.c_str());
|
||||
|
||||
@@ -1515,7 +1515,7 @@ qboolean Player::CondCanGetOffLadderTop(Conditional& condition)
|
||||
|
||||
angles.AngleVectorsLeft(&vForward);
|
||||
|
||||
vStart = origin - vForward * 12.0f;
|
||||
vStart = origin - vForward * 12.0f * 1.005f;
|
||||
vStart[2] += maxs[2] - 8.0f;
|
||||
|
||||
vEnd = vStart + vForward * 40.0f;
|
||||
|
||||
+215
-25
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "scriptexception.h"
|
||||
#include "vehicleturret.h"
|
||||
#include "weaputils.h"
|
||||
#include "g_bot.h"
|
||||
|
||||
// We assume that we have limited access to the server-side
|
||||
// and that most logic come from the playerstate_s structure
|
||||
@@ -64,8 +65,10 @@ BotController::BotController()
|
||||
m_botEyes.ofs[1] = 0;
|
||||
m_botEyes.ofs[2] = DEFAULT_VIEWHEIGHT;
|
||||
|
||||
m_iCuriousTime = 0;
|
||||
m_iAttackTime = 0;
|
||||
m_iCuriousTime = 0;
|
||||
m_iAttackTime = 0;
|
||||
m_iConfirmTime = 0;
|
||||
m_iEnemyEyesTag = -1;
|
||||
|
||||
m_iNextTauntTime = 0;
|
||||
|
||||
@@ -91,7 +94,7 @@ void BotController::Init(void)
|
||||
InitState_Curious(&botfuncs[1]);
|
||||
InitState_Grenade(&botfuncs[2]);
|
||||
InitState_Idle(&botfuncs[3]);
|
||||
InitState_Weapon(&botfuncs[4]);
|
||||
//InitState_Weapon(&botfuncs[4]);
|
||||
}
|
||||
|
||||
void BotController::GetUsercmd(usercmd_t *ucmd)
|
||||
@@ -160,6 +163,8 @@ void BotController::UpdateBotStates(void)
|
||||
movement.MoveThink(m_botCmd);
|
||||
rotation.TurnThink(m_botCmd, m_botEyes);
|
||||
CheckUse();
|
||||
|
||||
CheckValidWeapon();
|
||||
}
|
||||
|
||||
void BotController::CheckUse(void)
|
||||
@@ -177,7 +182,7 @@ void BotController::CheckUse(void)
|
||||
trace = G_Trace(start, vec_zero, vec_zero, end, controlledEnt, MASK_USABLE, false, "BotController::CheckUse");
|
||||
|
||||
// It may be a door
|
||||
if ((trace.allsolid || trace.startsolid || trace.fraction != 1.0f) && trace.entityNum) {
|
||||
if ((trace.allsolid || trace.startsolid || trace.fraction != 1.0f) && trace.ent) {
|
||||
if (trace.ent->entity->IsSubclassOfDoor()) {
|
||||
Door *door = static_cast<Door *>(trace.ent->entity);
|
||||
if (door->isOpen()) {
|
||||
@@ -195,6 +200,17 @@ void BotController::CheckUse(void)
|
||||
}
|
||||
}
|
||||
|
||||
void BotController::CheckValidWeapon() {
|
||||
Weapon* weapon = controlledEnt->GetActiveWeapon(WEAPON_MAIN);
|
||||
if (!weapon) {
|
||||
// If holstered, use the best weapon available
|
||||
UseWeaponWithAmmo();
|
||||
} else if (!weapon->HasAmmo(FIRE_PRIMARY) && !controlledEnt->GetNewActiveWeapon()) {
|
||||
// In case the current weapon has no ammo, use the best available weapon
|
||||
UseWeaponWithAmmo();
|
||||
}
|
||||
}
|
||||
|
||||
void BotController::SendCommand(const char *text)
|
||||
{
|
||||
char *buffer;
|
||||
@@ -372,7 +388,9 @@ Clear the bot's enemy
|
||||
void BotController::ClearEnemy(void)
|
||||
{
|
||||
m_iAttackTime = 0;
|
||||
m_iConfirmTime = 0;
|
||||
m_pEnemy = NULL;
|
||||
m_iEnemyEyesTag = -1;
|
||||
m_vOldEnemyPos = vec_zero;
|
||||
m_vLastEnemyPos = vec_zero;
|
||||
}
|
||||
@@ -459,6 +477,7 @@ void BotController::State_Reset(void)
|
||||
m_vLastEnemyPos = vec_zero;
|
||||
m_vLastDeathPos = vec_zero;
|
||||
m_pEnemy = NULL;
|
||||
m_iEnemyEyesTag = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -647,7 +666,24 @@ bool BotController::CheckCondition_Attack(void)
|
||||
maxDistance = Q_min(world->m_fAIVisionDistance, world->farplane_distance * 0.828);
|
||||
|
||||
if (controlledEnt->CanSee(sent, 80, maxDistance, false)) {
|
||||
m_pEnemy = sent;
|
||||
if (m_pEnemy != sent) {
|
||||
m_iEnemyEyesTag = -1;
|
||||
}
|
||||
|
||||
if (!m_pEnemy) {
|
||||
// Slight reaction time
|
||||
m_iConfirmTime = level.inttime + (200 + G_Random(200));
|
||||
m_iAttackTime = 0;
|
||||
}
|
||||
|
||||
m_pEnemy = sent;
|
||||
m_vLastEnemyPos = m_pEnemy->origin;
|
||||
if (level.inttime < m_iConfirmTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pEnemy && level.inttime >= m_iConfirmTime) {
|
||||
m_iAttackTime = level.inttime + 1000;
|
||||
return true;
|
||||
}
|
||||
@@ -674,10 +710,12 @@ void BotController::State_EndAttack(void)
|
||||
void BotController::State_Attack(void)
|
||||
{
|
||||
bool bMelee = false;
|
||||
bool bCanSee = false;
|
||||
float fMinDistance = 128;
|
||||
float fMinDistanceSquared = fMinDistance * fMinDistance;
|
||||
Weapon *pWeap = controlledEnt->GetActiveWeapon(WEAPON_MAIN);
|
||||
bool bNoMove = false;
|
||||
float fEnemyDistanceSquared;
|
||||
Weapon *pWeap = controlledEnt->GetActiveWeapon(WEAPON_MAIN);
|
||||
bool bNoMove = false;
|
||||
|
||||
if (!m_pEnemy || !IsValidEnemy(m_pEnemy)) {
|
||||
// Ignore dead enemies
|
||||
@@ -686,9 +724,11 @@ void BotController::State_Attack(void)
|
||||
}
|
||||
float fDistanceSquared = (m_pEnemy->origin - controlledEnt->origin).lengthSquared();
|
||||
|
||||
if (controlledEnt->CanSee(
|
||||
m_pEnemy, 20, Q_min(world->m_fAIVisionDistance, world->farplane_distance * 0.828), false
|
||||
)) {
|
||||
m_vOldEnemyPos = m_vLastEnemyPos;
|
||||
|
||||
bCanSee =
|
||||
controlledEnt->CanSee(m_pEnemy, 20, Q_min(world->m_fAIVisionDistance, world->farplane_distance * 0.828), false);
|
||||
if (bCanSee) {
|
||||
if (!pWeap) {
|
||||
return;
|
||||
}
|
||||
@@ -706,7 +746,7 @@ void BotController::State_Attack(void)
|
||||
float length;
|
||||
|
||||
length = controlledEnt->velocity.length();
|
||||
if ((length / sv_runspeed->value) > (pWeap->GetMaxFireMovement() * pWeap->GetMovementSpeed())) {
|
||||
if ((length / sv_runspeed->value) > (pWeap->GetMaxFireMovementMult())) {
|
||||
bNoMove = true;
|
||||
movement.ClearMove();
|
||||
}
|
||||
@@ -723,7 +763,9 @@ void BotController::State_Attack(void)
|
||||
if (controlledEnt->client->ps.stats[STAT_AMMO] > 0 || controlledEnt->client->ps.stats[STAT_CLIPAMMO] > 0) {
|
||||
if (fDistanceSquared <= fPrimaryBulletRangeSquared) {
|
||||
if (pWeap->IsSemiAuto()) {
|
||||
if (controlledEnt->client->ps.iViewModelAnim == VM_ANIM_IDLE || controlledEnt->client->ps.iViewModelAnim >= VM_ANIM_IDLE_0 && controlledEnt->client->ps.iViewModelAnim <= VM_ANIM_IDLE_2) {
|
||||
if (controlledEnt->client->ps.iViewModelAnim == VM_ANIM_IDLE
|
||||
|| controlledEnt->client->ps.iViewModelAnim >= VM_ANIM_IDLE_0
|
||||
&& controlledEnt->client->ps.iViewModelAnim <= VM_ANIM_IDLE_2) {
|
||||
if (fSpreadFactor < 0.25) {
|
||||
m_botCmd.buttons ^= BUTTON_ATTACKLEFT;
|
||||
if (pWeap->GetZoom()) {
|
||||
@@ -748,43 +790,86 @@ void BotController::State_Attack(void)
|
||||
m_botCmd.buttons &= ~(BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT);
|
||||
controlledEnt->ZoomOff();
|
||||
}
|
||||
} else if (pWeap->GetFireType(FIRE_SECONDARY) == FT_MELEE) {
|
||||
bMelee = true;
|
||||
} else {
|
||||
m_botCmd.buttons &= ~(BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT);
|
||||
controlledEnt->ZoomOff();
|
||||
}
|
||||
|
||||
if (pWeap->GetFireType(FIRE_SECONDARY) == FT_MELEE) {
|
||||
if (controlledEnt->client->ps.stats[STAT_AMMO] <= 0 && controlledEnt->client->ps.stats[STAT_CLIPAMMO] <= 0) {
|
||||
bMelee = true;
|
||||
} else if (fDistanceSquared <= fSecondaryBulletRangeSquared) {
|
||||
bMelee = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bMelee) {
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACKLEFT;
|
||||
|
||||
if (fDistanceSquared <= fSecondaryBulletRangeSquared) {
|
||||
m_botCmd.buttons ^= BUTTON_ATTACKRIGHT;
|
||||
} else {
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACKRIGHT;
|
||||
}
|
||||
} else {
|
||||
m_botCmd.buttons &= ~(BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT);
|
||||
controlledEnt->ZoomOff();
|
||||
}
|
||||
|
||||
m_iAttackTime = level.inttime + 1000;
|
||||
m_vOldEnemyPos = m_vLastEnemyPos;
|
||||
m_vLastEnemyPos = m_pEnemy->centroid;
|
||||
m_iAttackTime = level.inttime + 1000;
|
||||
m_iAttackStopAimTime = level.inttime + 3000;
|
||||
m_vLastEnemyPos = m_pEnemy->centroid;
|
||||
} else {
|
||||
m_botCmd.buttons &= ~(BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT);
|
||||
fMinDistanceSquared = 0;
|
||||
}
|
||||
|
||||
rotation.AimAt(m_pEnemy->centroid + Vector(G_CRandom(8), G_CRandom(8), G_CRandom(8)));
|
||||
if (bCanSee || level.inttime < m_iAttackStopAimTime) {
|
||||
Vector vRandomOffset;
|
||||
Vector vTarget;
|
||||
orientation_t eyes_or;
|
||||
|
||||
if (m_iEnemyEyesTag == -1) {
|
||||
// Cache the tag
|
||||
m_iEnemyEyesTag = gi.Tag_NumForName(m_pEnemy->edict->tiki, "eyes bone");
|
||||
}
|
||||
|
||||
if (m_iEnemyEyesTag != -1) {
|
||||
// Use the enemy's eyes bone
|
||||
m_pEnemy->GetTag(m_iEnemyEyesTag, &eyes_or);
|
||||
|
||||
vRandomOffset = Vector(G_CRandom(8), G_CRandom(8), -G_Random(32));
|
||||
vTarget = eyes_or.origin + vRandomOffset;
|
||||
rotation.AimAt(eyes_or.origin + vRandomOffset);
|
||||
} else {
|
||||
vRandomOffset = Vector(G_CRandom(8), G_CRandom(8), 16 + G_Random(m_pEnemy->viewheight - 16));
|
||||
vTarget = m_pEnemy->origin + vRandomOffset;
|
||||
}
|
||||
|
||||
rotation.AimAt(vTarget);
|
||||
} else {
|
||||
AimAtAimNode();
|
||||
}
|
||||
|
||||
if (bNoMove) {
|
||||
return;
|
||||
}
|
||||
|
||||
fEnemyDistanceSquared = (controlledEnt->origin - m_vLastEnemyPos).lengthSquared();
|
||||
|
||||
if ((!movement.MoveToBestAttractivePoint(5) && !movement.IsMoving())
|
||||
|| (m_vOldEnemyPos != m_vLastEnemyPos && !movement.MoveDone())) {
|
||||
if (!bMelee) {
|
||||
if ((controlledEnt->origin - m_vLastEnemyPos).lengthSquared() < fMinDistanceSquared) {
|
||||
|| (m_vOldEnemyPos != m_vLastEnemyPos && !movement.MoveDone()) || fEnemyDistanceSquared < fMinDistanceSquared) {
|
||||
if (!bMelee || !bCanSee) {
|
||||
if (fEnemyDistanceSquared < fMinDistanceSquared) {
|
||||
Vector vDir = controlledEnt->origin - m_vLastEnemyPos;
|
||||
VectorNormalizeFast(vDir);
|
||||
|
||||
movement.AvoidPath(m_vLastEnemyPos, fMinDistance, Vector(controlledEnt->orientation[1]) * 512);
|
||||
} else {
|
||||
movement.MoveNear(m_vLastEnemyPos, fMinDistance);
|
||||
movement.MoveTo(m_vLastEnemyPos);
|
||||
}
|
||||
|
||||
if (!bCanSee && movement.MoveDone()) {
|
||||
// Lost track of the enemy
|
||||
ClearEnemy();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
movement.MoveTo(m_vLastEnemyPos);
|
||||
@@ -851,6 +936,102 @@ void BotController::State_BeginWeapon(void)
|
||||
SendCommand(va("use \"%s\"", weap->model.c_str()));
|
||||
}
|
||||
|
||||
Weapon* BotController::FindWeaponWithAmmo() {
|
||||
|
||||
Weapon *next;
|
||||
int n;
|
||||
int j;
|
||||
int bestrank;
|
||||
Weapon *bestweapon;
|
||||
const Container<int>& inventory = controlledEnt->getInventory();
|
||||
|
||||
n = inventory.NumObjects();
|
||||
|
||||
// Search until we find the best weapon with ammo
|
||||
bestweapon = NULL;
|
||||
bestrank = -999999;
|
||||
|
||||
for (j = 1; j <= n; j++) {
|
||||
next = (Weapon *)G_GetEntity(inventory.ObjectAt(j));
|
||||
|
||||
assert(next);
|
||||
if (!next->IsSubclassOfWeapon() || next->IsSubclassOfInventoryItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next->GetWeaponClass() & WEAPON_CLASS_THROWABLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next->GetRank() < bestrank) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!next->HasAmmo(FIRE_PRIMARY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bestweapon = (Weapon*)next;
|
||||
bestrank = bestweapon->GetRank();
|
||||
}
|
||||
|
||||
return bestweapon;
|
||||
}
|
||||
|
||||
Weapon* BotController::FindMeleeWeapon() {
|
||||
|
||||
Weapon *next;
|
||||
int n;
|
||||
int j;
|
||||
int bestrank;
|
||||
Weapon *bestweapon;
|
||||
const Container<int>& inventory = controlledEnt->getInventory();
|
||||
|
||||
n = inventory.NumObjects();
|
||||
|
||||
// Search until we find the best weapon with ammo
|
||||
bestweapon = NULL;
|
||||
bestrank = -999999;
|
||||
|
||||
for (j = 1; j <= n; j++) {
|
||||
next = (Weapon *)G_GetEntity(inventory.ObjectAt(j));
|
||||
|
||||
assert(next);
|
||||
if (!next->IsSubclassOfWeapon() || next->IsSubclassOfInventoryItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next->GetRank() < bestrank) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next->GetFireType(FIRE_SECONDARY) != FT_MELEE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bestweapon = (Weapon*)next;
|
||||
bestrank = bestweapon->GetRank();
|
||||
}
|
||||
|
||||
return bestweapon;
|
||||
}
|
||||
|
||||
void BotController::UseWeaponWithAmmo() {
|
||||
Weapon* bestWeapon = FindWeaponWithAmmo();
|
||||
if (!bestWeapon) {
|
||||
//
|
||||
// If there is no weapon with ammo, fallback to a weapon that can melee
|
||||
//
|
||||
bestWeapon = FindMeleeWeapon();
|
||||
}
|
||||
|
||||
if (!bestWeapon || bestWeapon == controlledEnt->GetActiveWeapon(WEAPON_MAIN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
controlledEnt->useWeapon(bestWeapon, WEAPON_MAIN);
|
||||
}
|
||||
|
||||
void BotController::Spawned(void)
|
||||
{
|
||||
ClearEnemy();
|
||||
@@ -901,6 +1082,15 @@ void BotController::Killed(Event *ev)
|
||||
event.AddString("auto");
|
||||
|
||||
controlledEnt->ProcessEvent(event);
|
||||
|
||||
//
|
||||
// This is useful to change nationality in Spearhead and Breakthrough
|
||||
// this allows the AI to use more weapons
|
||||
//
|
||||
Info_SetValueForKey(controlledEnt->client->pers.userinfo, "dm_playermodel", G_GetRandomAlliedPlayerModel());
|
||||
Info_SetValueForKey(controlledEnt->client->pers.userinfo, "dm_playergermanmodel", G_GetRandomGermanPlayerModel());
|
||||
|
||||
G_ClientUserinfoChanged(controlledEnt->edict, controlledEnt->client->pers.userinfo);
|
||||
}
|
||||
|
||||
void BotController::GotKill(Event *ev)
|
||||
|
||||
+13
-4
@@ -110,12 +110,13 @@ private:
|
||||
float m_fYawSpeedMult;
|
||||
};
|
||||
|
||||
class BotState {
|
||||
class BotState
|
||||
{
|
||||
public:
|
||||
virtual bool CheckCondition() const = 0;
|
||||
virtual void Begin() = 0;
|
||||
virtual void End() = 0;
|
||||
virtual void Think() = 0;
|
||||
virtual void Begin() = 0;
|
||||
virtual void End() = 0;
|
||||
virtual void Think() = 0;
|
||||
};
|
||||
|
||||
class BotController : public Listener
|
||||
@@ -137,12 +138,15 @@ private:
|
||||
// States
|
||||
int m_iCuriousTime;
|
||||
int m_iAttackTime;
|
||||
int m_iConfirmTime;
|
||||
int m_iAttackStopAimTime;
|
||||
Vector m_vLastCuriousPos;
|
||||
Vector m_vNewCuriousPos;
|
||||
Vector m_vOldEnemyPos;
|
||||
Vector m_vLastEnemyPos;
|
||||
Vector m_vLastDeathPos;
|
||||
SafePtr<Sentient> m_pEnemy;
|
||||
int m_iEnemyEyesTag;
|
||||
|
||||
// Input
|
||||
usercmd_t m_botCmd;
|
||||
@@ -157,7 +161,12 @@ private:
|
||||
int m_iNextTauntTime;
|
||||
|
||||
private:
|
||||
Weapon* FindWeaponWithAmmo(void);
|
||||
Weapon* FindMeleeWeapon(void);
|
||||
void UseWeaponWithAmmo(void);
|
||||
|
||||
void CheckUse(void);
|
||||
void CheckValidWeapon(void);
|
||||
|
||||
void State_DefaultBegin(void);
|
||||
void State_DefaultEnd(void);
|
||||
|
||||
@@ -118,14 +118,44 @@ void BotMovement::MoveThink(usercmd_t& botcmd)
|
||||
}
|
||||
|
||||
if (m_bTempAway) {
|
||||
Vector nextPos;
|
||||
Vector dir;
|
||||
|
||||
m_bTempAway = true;
|
||||
m_iTempAwayTime = level.inttime + 750;
|
||||
m_iNumBlocks++;
|
||||
|
||||
// Try to backward a little
|
||||
if (m_Path.CurrentNode()) {
|
||||
nextPos = m_Path.CurrentNode()->point;
|
||||
} else {
|
||||
nextPos = m_vTargetPos;
|
||||
}
|
||||
|
||||
m_Path.Clear();
|
||||
m_Path.ForceShortLookahead();
|
||||
m_vCurrentGoal = controlledEntity->origin + Vector(G_CRandom(512), G_CRandom(512), G_CRandom(512));
|
||||
|
||||
if (rand() % 10 != 0) {
|
||||
dir = nextPos - controlledEntity->origin;
|
||||
dir.z = 0;
|
||||
dir.normalize();
|
||||
|
||||
if (dir.x < -0.5 || dir.x > 0.5) {
|
||||
dir.x *= 4;
|
||||
dir.y /= 4;
|
||||
} else if (dir.y < -0.5 || dir.y > 0.5) {
|
||||
dir.x /= 4;
|
||||
dir.y *= 4;
|
||||
} else {
|
||||
dir.x = G_CRandom(2);
|
||||
dir.y = G_CRandom(2);
|
||||
}
|
||||
|
||||
m_vCurrentGoal = nextPos + dir * 128;
|
||||
} else {
|
||||
m_vCurrentGoal = controlledEntity->origin + Vector(G_CRandom(512), G_CRandom(512), G_CRandom(512));
|
||||
}
|
||||
|
||||
} else {
|
||||
m_iNumBlocks = 0;
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ void BotRotation::TurnThink(usercmd_t& botcmd, usereyes_t& eyeinfo)
|
||||
m_vTargetAng[PITCH] -= 360;
|
||||
}
|
||||
|
||||
factor = 0.25f;
|
||||
factor = 0.5f;
|
||||
maxchange = 360;
|
||||
|
||||
if (maxchange < 240) {
|
||||
@@ -84,7 +84,7 @@ void BotRotation::TurnThink(usercmd_t& botcmd, usereyes_t& eyeinfo)
|
||||
m_vCurrentAng[i] += anglespeed;
|
||||
m_vCurrentAng[i] = AngleMod(m_vCurrentAng[i]);
|
||||
|
||||
//demping
|
||||
//damping
|
||||
m_vAngSpeed[i] *= 0.2 * (1 - factor);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ Make the bot face to the specified direction
|
||||
*/
|
||||
void BotRotation::AimAt(Vector vPos)
|
||||
{
|
||||
Vector vDelta = vPos - controlledEntity->centroid;
|
||||
Vector vDelta = vPos - controlledEntity->EyePosition();
|
||||
|
||||
VectorNormalize(vDelta);
|
||||
vectoangles(vDelta, m_vTargetAng);
|
||||
|
||||
@@ -2126,7 +2126,8 @@ Event EV_ScriptOrigin_GetAngle
|
||||
NULL,
|
||||
"get the angles of the entity using just one value.\n"
|
||||
"Gets the yaw of the entity or an up and down\n"
|
||||
"direction if newAngle is [0-359] or -1 or -2"
|
||||
"direction if newAngle is [0-359] or -1 or -2",
|
||||
EV_GETTER
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(ScriptSlave, ScriptOrigin, "script_origin") {
|
||||
@@ -2173,7 +2174,10 @@ void ScriptOrigin::SetAngleEvent(Event* ev)
|
||||
|
||||
void ScriptOrigin::GetAngleEvent(Event* ev)
|
||||
{
|
||||
ev->AddFloat(G_GetAngle(angles));
|
||||
Vector forward;
|
||||
|
||||
angles.AngleVectorsLeft(&forward);
|
||||
ev->AddFloat(G_GetAngle(forward));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
+174
-134
@@ -1435,6 +1435,15 @@ Event EV_ScriptThread_FileRead
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_ScriptThread_FileClose
|
||||
(
|
||||
"fclose",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"filehandle",
|
||||
"Closes file of given file handle",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_ScriptThread_FileClose2
|
||||
(
|
||||
"fclose",
|
||||
EV_DEFAULT,
|
||||
@@ -2191,6 +2200,7 @@ CLASS_DECLARATION(Listener, ScriptThread, NULL) {
|
||||
{&EV_ScriptThread_Earthquake2, &ScriptThread::Earthquake },
|
||||
{&EV_ScriptThread_FadeSound, &ScriptThread::FadeSound },
|
||||
{&EV_ScriptThread_FileClose, &ScriptThread::FileClose },
|
||||
{&EV_ScriptThread_FileClose2, &ScriptThread::FileClose },
|
||||
{&EV_ScriptThread_FileCopy, &ScriptThread::FileCopy },
|
||||
{&EV_ScriptThread_FileEof, &ScriptThread::FileEof },
|
||||
{&EV_ScriptThread_FileError, &ScriptThread::FileError },
|
||||
@@ -2478,7 +2488,7 @@ void ScriptThread::Stop(void)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptThread::Wait(float time)
|
||||
void ScriptThread::Wait(int time)
|
||||
{
|
||||
StartTiming(level.inttime + time);
|
||||
m_ScriptVM->Suspend();
|
||||
@@ -2496,7 +2506,7 @@ void ScriptThread::Getcvar(Event *ev)
|
||||
str s = gi.Cvar_Get(varName.c_str(), "", 0)->string;
|
||||
|
||||
if (strstr(s.c_str(), ".")) {
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
for (size_t i = s.length() - 1; i >= 0; i--) {
|
||||
if (s[i] == '0') {
|
||||
s[i] = 0;
|
||||
} else {
|
||||
@@ -2797,7 +2807,7 @@ void ScriptThread::IPrintln(Event *ev)
|
||||
sString += ev->GetString(i);
|
||||
}
|
||||
|
||||
G_PrintToAllClients(gi.LV_ConvertString(sString), false);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_YELLOW "%s\n\"", gi.LV_ConvertString(sString.c_str()));
|
||||
}
|
||||
|
||||
void ScriptThread::IPrintlnBold(Event *ev)
|
||||
@@ -2810,7 +2820,7 @@ void ScriptThread::IPrintlnBold(Event *ev)
|
||||
sString += ev->GetString(i);
|
||||
}
|
||||
|
||||
G_PrintToAllClients(gi.LV_ConvertString(sString), true);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_WHITE "%s\n\"", gi.LV_ConvertString(sString.c_str()));
|
||||
}
|
||||
|
||||
void ScriptThread::IPrintln_NoLoc(Event *ev)
|
||||
@@ -2823,7 +2833,7 @@ void ScriptThread::IPrintln_NoLoc(Event *ev)
|
||||
sString += ev->GetString(i);
|
||||
}
|
||||
|
||||
G_PrintToAllClients(sString, false);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_YELLOW "%s\n\"", sString.c_str());
|
||||
}
|
||||
|
||||
void ScriptThread::IPrintlnBold_NoLoc(Event *ev)
|
||||
@@ -2836,7 +2846,7 @@ void ScriptThread::IPrintlnBold_NoLoc(Event *ev)
|
||||
sString += ev->GetString(i);
|
||||
}
|
||||
|
||||
G_PrintToAllClients(sString, true);
|
||||
gi.SendServerCommand(-1, "print \"" HUD_MESSAGE_WHITE "%s\n\"", sString.c_str());
|
||||
}
|
||||
|
||||
void ScriptThread::MPrint(Event *ev)
|
||||
@@ -4093,7 +4103,7 @@ void ScriptThread::EventRadiusDamage(Event *ev)
|
||||
|
||||
void ScriptThread::EventBspTransition(Event *ev)
|
||||
{
|
||||
str map = ev->GetString(1);
|
||||
str map = ev->GetString(1);
|
||||
bool skipFade = false;
|
||||
|
||||
if (ev->NumArgs() >= 2) {
|
||||
@@ -4203,12 +4213,12 @@ void ScriptThread::EventPointsWithinDist(Event *ev)
|
||||
{
|
||||
Vector delta;
|
||||
Vector v1, v2;
|
||||
float fDistance;
|
||||
|
||||
v1 = ev->GetVector(1);
|
||||
v2 = ev->GetVector(2);
|
||||
float fDistance;
|
||||
|
||||
v1 = ev->GetVector(1);
|
||||
v2 = ev->GetVector(2);
|
||||
fDistance = ev->GetFloat(3);
|
||||
delta = v1 - v2;
|
||||
delta = v1 - v2;
|
||||
|
||||
// check squared distance
|
||||
ev->AddInteger(delta.lengthSquared() < Square(fDistance));
|
||||
@@ -5361,15 +5371,15 @@ void ScriptThread::FileOpen(Event *ev)
|
||||
|
||||
f = fopen(filename, accesstype);
|
||||
|
||||
if (f == NULL) {
|
||||
ev->AddInteger(0);
|
||||
return;
|
||||
} else {
|
||||
ev->AddInteger((int)(size_t)f);
|
||||
Com_sprintf(buf, sizeof(buf), "%i", scriptfiles->integer + 1);
|
||||
gi.cvar_set("sv_scriptfiles", buf);
|
||||
if (!f) {
|
||||
ev->AddNil();
|
||||
return;
|
||||
}
|
||||
|
||||
ev->AddListener(new OSFile(f));
|
||||
|
||||
Com_sprintf(buf, sizeof(buf), "%i", scriptfiles->integer + 1);
|
||||
gi.cvar_set("sv_scriptfiles", buf);
|
||||
}
|
||||
|
||||
void ScriptThread::FileWrite(Event *ev) {}
|
||||
@@ -5378,11 +5388,10 @@ void ScriptThread::FileRead(Event *ev) {}
|
||||
|
||||
void ScriptThread::FileClose(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
char buf[16] = {0};
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
FILE *f = NULL;
|
||||
char buf[16] = {0};
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5390,57 +5399,30 @@ void ScriptThread::FileClose(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fclose!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
|
||||
/*if( (int)scriptFiles[0].f != id && (int)scriptFiles[1].f != id )
|
||||
{
|
||||
gi.Printf("Wrong file handle for fclose!\n");
|
||||
return;
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
if( (int)scriptFiles[0].f == id )
|
||||
{
|
||||
scriptFiles[0].inUse = 0;
|
||||
fclose( scriptFiles[0].f );
|
||||
return;
|
||||
}
|
||||
else if( (int)scriptFiles[1].f == id )
|
||||
{
|
||||
scriptFiles[1].inUse = 0;
|
||||
fclose( scriptFiles[1].f );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.Printf("Unknown error while closing file - fclose!\n");
|
||||
return;
|
||||
}*/
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
if (f == NULL) {
|
||||
throw ScriptException("File handle is NULL for fclose!\n");
|
||||
}
|
||||
|
||||
ret = fclose(f);
|
||||
// delete the file object
|
||||
delete osFile;
|
||||
|
||||
if (ret == 0) {
|
||||
ev->AddInteger(0);
|
||||
Com_sprintf(buf, sizeof(buf), "%i", scriptfiles->integer - 1);
|
||||
gi.cvar_set("sv_scriptfiles", buf);
|
||||
return;
|
||||
} else {
|
||||
ev->AddInteger(ret);
|
||||
return;
|
||||
}
|
||||
Com_sprintf(buf, sizeof(buf), "%i", scriptfiles->integer - 1);
|
||||
gi.cvar_set("sv_scriptfiles", buf);
|
||||
}
|
||||
|
||||
void ScriptThread::FileEof(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5448,9 +5430,12 @@ void ScriptThread::FileEof(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for feof!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
ret = feof(f);
|
||||
|
||||
@@ -5459,7 +5444,7 @@ void ScriptThread::FileEof(Event *ev)
|
||||
|
||||
void ScriptThread::FileSeek(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int pos = 0;
|
||||
long int offset = 0;
|
||||
@@ -5472,9 +5457,12 @@ void ScriptThread::FileSeek(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fseek!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
offset = ev->GetInteger(2);
|
||||
|
||||
@@ -5495,7 +5483,7 @@ void ScriptThread::FileSeek(Event *ev)
|
||||
|
||||
void ScriptThread::FileTell(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
long int ret = 0;
|
||||
FILE *f = NULL;
|
||||
@@ -5506,9 +5494,12 @@ void ScriptThread::FileTell(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for ftell!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
ret = ftell(f);
|
||||
|
||||
@@ -5517,7 +5508,7 @@ void ScriptThread::FileTell(Event *ev)
|
||||
|
||||
void ScriptThread::FileRewind(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
long int ret = 0;
|
||||
FILE *f = NULL;
|
||||
@@ -5528,20 +5519,23 @@ void ScriptThread::FileRewind(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for frewind!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
rewind(f);
|
||||
}
|
||||
|
||||
void ScriptThread::FilePutc(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
int c = 0;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
int c = 0;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5549,9 +5543,12 @@ void ScriptThread::FilePutc(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fputc!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
c = ev->GetInteger(2);
|
||||
|
||||
@@ -5562,11 +5559,11 @@ void ScriptThread::FilePutc(Event *ev)
|
||||
|
||||
void ScriptThread::FilePuts(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
str c;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
str c;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5574,9 +5571,12 @@ void ScriptThread::FilePuts(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fputs!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
c = ev->GetString(2);
|
||||
//gi.Printf("Putting line into a file\n");
|
||||
@@ -5587,10 +5587,10 @@ void ScriptThread::FilePuts(Event *ev)
|
||||
|
||||
void ScriptThread::FileGetc(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5598,9 +5598,12 @@ void ScriptThread::FileGetc(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fgetc!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
ret = fgetc(f);
|
||||
|
||||
@@ -5609,12 +5612,12 @@ void ScriptThread::FileGetc(Event *ev)
|
||||
|
||||
void ScriptThread::FileGets(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int maxCount = 0;
|
||||
FILE *f = NULL;
|
||||
char *c = NULL;
|
||||
char *buff = NULL;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int maxCount = 0;
|
||||
FILE *f = NULL;
|
||||
char *c = NULL;
|
||||
char *buff = NULL;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5622,9 +5625,12 @@ void ScriptThread::FileGets(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fgets!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
maxCount = ev->GetInteger(2);
|
||||
|
||||
@@ -5657,10 +5663,10 @@ void ScriptThread::FileGets(Event *ev)
|
||||
|
||||
void ScriptThread::FileError(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5668,9 +5674,12 @@ void ScriptThread::FileError(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for ferror!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
ret = ferror(f);
|
||||
|
||||
@@ -5679,10 +5688,10 @@ void ScriptThread::FileError(Event *ev)
|
||||
|
||||
void ScriptThread::FileFlush(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5690,9 +5699,12 @@ void ScriptThread::FileFlush(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fflush!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
ret = fflush(f);
|
||||
|
||||
@@ -5701,7 +5713,6 @@ void ScriptThread::FileFlush(Event *ev)
|
||||
|
||||
void ScriptThread::FileExists(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
FILE *f = 0;
|
||||
str filename;
|
||||
@@ -5729,13 +5740,13 @@ void ScriptThread::FileExists(Event *ev)
|
||||
|
||||
void ScriptThread::FileReadAll(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
FILE *f = NULL;
|
||||
char *ret = NULL;
|
||||
long currentPos = 0;
|
||||
size_t size = 0;
|
||||
size_t sizeRead = 0;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
FILE *f = NULL;
|
||||
char *ret = NULL;
|
||||
long currentPos = 0;
|
||||
size_t size = 0;
|
||||
size_t sizeRead = 0;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5743,9 +5754,12 @@ void ScriptThread::FileReadAll(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for freadall!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)id;
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
currentPos = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
@@ -5769,11 +5783,11 @@ void ScriptThread::FileReadAll(Event *ev)
|
||||
|
||||
void ScriptThread::FileSaveAll(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
FILE *f = NULL;
|
||||
size_t sizeWrite = 0;
|
||||
str text;
|
||||
OSFile *osFile = NULL;
|
||||
int numArgs = 0;
|
||||
FILE *f = NULL;
|
||||
size_t sizeWrite = 0;
|
||||
str text;
|
||||
|
||||
numArgs = ev->NumArgs();
|
||||
|
||||
@@ -5781,8 +5795,12 @@ void ScriptThread::FileSaveAll(Event *ev)
|
||||
throw ScriptException("Wrong arguments count for fsaveall!\n");
|
||||
}
|
||||
|
||||
id = ev->GetInteger(1);
|
||||
f = (FILE *)id;
|
||||
osFile = (OSFile *)ev->GetListener(1);
|
||||
if (!osFile || !osFile->isSubclassOf(OSFile)) {
|
||||
throw ScriptException("Not a file!\n");
|
||||
}
|
||||
|
||||
f = (FILE *)osFile->getOSFile();
|
||||
|
||||
text = ev->GetString(2);
|
||||
|
||||
@@ -5798,7 +5816,6 @@ void ScriptThread::FileSaveAll(Event *ev)
|
||||
|
||||
void ScriptThread::FileRemove(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
str filename;
|
||||
@@ -5822,7 +5839,6 @@ void ScriptThread::FileRemove(Event *ev)
|
||||
|
||||
void ScriptThread::FileRename(Event *ev)
|
||||
{
|
||||
int id = 0;
|
||||
int numArgs = 0;
|
||||
int ret = 0;
|
||||
str oldfilename, newfilename;
|
||||
@@ -7049,4 +7065,28 @@ void ScriptThread::TraceDetails(Event *ev)
|
||||
array.setArrayAtRef(entityIndex, entityValue);
|
||||
|
||||
ev->AddValue(array);
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(Listener, OSFile, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
OSFile::OSFile()
|
||||
: file(NULL)
|
||||
{}
|
||||
|
||||
OSFile::OSFile(void *inFile)
|
||||
: file(inFile)
|
||||
{}
|
||||
|
||||
OSFile::~OSFile()
|
||||
{
|
||||
if (file) {
|
||||
fclose((FILE *)file);
|
||||
}
|
||||
}
|
||||
|
||||
void *OSFile::getOSFile() const
|
||||
{
|
||||
return file;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
void Execute(Event *ev);
|
||||
void Execute();
|
||||
void Execute(ScriptVariable *data, int dataSize);
|
||||
void Wait(float time);
|
||||
void Wait(int time);
|
||||
void Pause(void);
|
||||
void ScriptExecute(ScriptVariable *data, int dataSize, ScriptVariable& returnValue);
|
||||
void ScriptExecuteInternal(ScriptVariable *data = NULL, int dataSize = 0);
|
||||
@@ -345,4 +345,19 @@ public:
|
||||
void UnregisterEvent(Event *ev);
|
||||
void VisionGetNaked(Event *ev);
|
||||
void VisionSetNaked(Event *ev);
|
||||
};
|
||||
};
|
||||
|
||||
class OSFile : public Listener
|
||||
{
|
||||
CLASS_PROTOTYPE(OSFile);
|
||||
|
||||
public:
|
||||
OSFile();
|
||||
OSFile(void *inFile);
|
||||
~OSFile();
|
||||
|
||||
void *getOSFile() const;
|
||||
|
||||
private:
|
||||
void *file;
|
||||
};
|
||||
+26
-6
@@ -531,7 +531,7 @@ Event EV_Sentient_ForceDropWeapon2
|
||||
);
|
||||
Event EV_Sentient_ForceDropHealth
|
||||
(
|
||||
"forcedropweapon",
|
||||
"forcedrophealth",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -540,7 +540,7 @@ Event EV_Sentient_ForceDropHealth
|
||||
);
|
||||
Event EV_Sentient_ForceDropHealth2
|
||||
(
|
||||
"forcedropweapon",
|
||||
"forcedrophealth",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -578,6 +578,24 @@ Event EV_Sentient_GetNewActiveWeap
|
||||
"gets new active weapon",
|
||||
EV_RETURN
|
||||
);
|
||||
Event EV_Sentient_GetNewActiveWeapon
|
||||
(
|
||||
"newActiveWeapon",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"gets new active weapon",
|
||||
EV_GETTER
|
||||
);
|
||||
Event EV_Sentient_GetNewActiveWeaponHand
|
||||
(
|
||||
"newActiveWeaponHand",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"gets the hand of the new active weapon",
|
||||
EV_GETTER
|
||||
);
|
||||
Event EV_Sentient_GetActiveWeap
|
||||
(
|
||||
"getactiveweap",
|
||||
@@ -656,10 +674,12 @@ CLASS_DECLARATION(Animate, Sentient, NULL) {
|
||||
{&EV_Sentient_ForceDropWeapon2, &Sentient::EventForceDropWeapon },
|
||||
{&EV_Sentient_GetForceDropWeapon, &Sentient::EventGetForceDropWeapon },
|
||||
|
||||
{&EV_Sentient_GetActiveWeap, &Sentient::GetActiveWeap },
|
||||
{&EV_Sentient_GetNewActiveWeap, &Sentient::GetNewActiveWeapon },
|
||||
{&EV_Sentient_Client_Landing, &Sentient::EventClientLanding },
|
||||
{NULL, NULL }
|
||||
{&EV_Sentient_GetActiveWeap, &Sentient::GetActiveWeap },
|
||||
{&EV_Sentient_GetNewActiveWeap, &Sentient::GetNewActiveWeaponOld },
|
||||
{&EV_Sentient_GetNewActiveWeapon, &Sentient::GetNewActiveWeapon },
|
||||
{&EV_Sentient_GetNewActiveWeaponHand, &Sentient::GetNewActiveWeaponHand },
|
||||
{&EV_Sentient_Client_Landing, &Sentient::EventClientLanding },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
Container<Sentient *> SentientList;
|
||||
|
||||
@@ -321,6 +321,7 @@ public:
|
||||
Weapon *GetNewActiveWeapon(void);
|
||||
weaponhand_t GetNewActiveWeaponHand(void);
|
||||
void ClearNewActiveWeapon(void);
|
||||
void SetNewActiveWeapon(Weapon* weapon, weaponhand_t hand);
|
||||
void Holster(qboolean putaway);
|
||||
void SafeHolster(qboolean putaway);
|
||||
void ActivateNewWeapon(void);
|
||||
@@ -355,12 +356,17 @@ public:
|
||||
// Custom openmohaa stuff
|
||||
//
|
||||
void GetActiveWeap(Event *ev);
|
||||
void GetNewActiveWeaponOld(Event *ev);
|
||||
void GetNewActiveWeapon(Event *ev);
|
||||
void GetNewActiveWeaponHand(Event *ev);
|
||||
void EventClientLanding(Event *ev);
|
||||
|
||||
void FootstepMain(trace_t *trace, int iRunning, int iEquipment);
|
||||
void Footstep(const char *szTagName, int iRunning, int iEquipment);
|
||||
void LandingSound(float volume, int iEquipment);
|
||||
|
||||
const Container<int>& getInventory() const;
|
||||
const Container<Ammo*>& getAmmoInventory() const;
|
||||
};
|
||||
|
||||
typedef SafePtr<Sentient> SentientPtr;
|
||||
|
||||
@@ -54,8 +54,13 @@ Weapon *Sentient::GetNewActiveWeapon(void)
|
||||
|
||||
void Sentient::ClearNewActiveWeapon(void)
|
||||
{
|
||||
newActiveWeapon.weapon.Clear();
|
||||
newActiveWeapon.hand = WEAPON_ERROR;
|
||||
SetNewActiveWeapon(NULL, WEAPON_ERROR);
|
||||
}
|
||||
|
||||
void Sentient::SetNewActiveWeapon(Weapon* weapon, weaponhand_t hand)
|
||||
{
|
||||
newActiveWeapon.weapon = weapon;
|
||||
newActiveWeapon.hand = hand;
|
||||
}
|
||||
|
||||
void Sentient::EventGiveAmmo(Event *ev)
|
||||
@@ -1097,6 +1102,9 @@ void Sentient::useWeapon(const char *weaponname, weaponhand_t hand)
|
||||
|
||||
// Find the item in the sentient's inventory
|
||||
weapon = (Weapon *)FindItem(weaponname);
|
||||
if (!weapon) {
|
||||
weapon = (Weapon *)FindItemByExternalName(weaponname);
|
||||
}
|
||||
|
||||
// If it exists, then make the change to the slot number specified
|
||||
if (weapon) {
|
||||
@@ -1114,8 +1122,7 @@ void Sentient::useWeapon(Weapon *weapon, weaponhand_t hand)
|
||||
}
|
||||
|
||||
if (newActiveWeapon.weapon) {
|
||||
newActiveWeapon.weapon = weapon;
|
||||
newActiveWeapon.hand = hand;
|
||||
SetNewActiveWeapon(weapon, hand);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1127,14 +1134,15 @@ void Sentient::useWeapon(Weapon *weapon, weaponhand_t hand)
|
||||
activeWeaponList[WEAPON_OFFHAND]->PutAway();
|
||||
}
|
||||
|
||||
if (activeWeaponList[WEAPON_MAIN] && activeWeaponList[WEAPON_MAIN] != weapon) {
|
||||
if (activeWeaponList[WEAPON_MAIN] == weapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeWeaponList[WEAPON_MAIN]) {
|
||||
activeWeaponList[WEAPON_MAIN]->PutAway();
|
||||
}
|
||||
|
||||
newActiveWeapon.weapon = weapon;
|
||||
newActiveWeapon.hand = hand;
|
||||
|
||||
//ChangeWeapon( weapon, hand );
|
||||
SetNewActiveWeapon(weapon, hand);
|
||||
}
|
||||
|
||||
void Sentient::EventUseWeaponClass(Event *ev)
|
||||
@@ -1287,11 +1295,23 @@ Ammo *Sentient::FindAmmoByName(str name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sentient::GetNewActiveWeapon(Event *ev)
|
||||
void Sentient::GetNewActiveWeaponOld(Event *ev)
|
||||
{
|
||||
ScriptDeprecatedAltVariable("newActiveWeapon");
|
||||
|
||||
ev->AddEntity(GetNewActiveWeapon());
|
||||
}
|
||||
|
||||
void Sentient::GetNewActiveWeapon(Event* ev)
|
||||
{
|
||||
ev->AddEntity(GetNewActiveWeapon());
|
||||
}
|
||||
|
||||
void Sentient::GetNewActiveWeaponHand(Event* ev)
|
||||
{
|
||||
ev->AddInteger(GetNewActiveWeaponHand());
|
||||
}
|
||||
|
||||
void Sentient::GetActiveWeap(Event *ev)
|
||||
{
|
||||
weaponhand_t weaponhand;
|
||||
@@ -1308,3 +1328,11 @@ void Sentient::GetActiveWeap(Event *ev)
|
||||
|
||||
ev->AddEntity(weapon);
|
||||
}
|
||||
|
||||
const Container<int>& Sentient::getInventory() const {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
const Container<Ammo*>& Sentient::getAmmoInventory() const {
|
||||
return ammo_inventory;
|
||||
}
|
||||
+78
-62
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -122,106 +122,107 @@ Event EV_SmokeGrenade_SetMaxAlpha
|
||||
"sets maximum opacity of an individual smoke particle, in 0-1 range"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(EffectEntity, SmokeGrenade, "smokegrenade")
|
||||
{
|
||||
{ &EV_SmokeGrenade_SetSpawnRate, &SmokeGrenade::EventSetSpawnrate },
|
||||
{ &EV_SmokeGrenade_SetBouncefactor, &SmokeGrenade::EventSetBouncefactor },
|
||||
{ &EV_SmokeGrenade_SetLife, &SmokeGrenade::EventSetLife },
|
||||
{ &EV_SmokeGrenade_SetSpawnLife, &SmokeGrenade::EventSetSpawnLife },
|
||||
{ &EV_SmokeGrenade_SetScalerate, &SmokeGrenade::EventSetScalerate },
|
||||
{ &EV_SmokeGrenade_SetVelocity, &SmokeGrenade::EventSetVelocity },
|
||||
{ &EV_SmokeGrenade_SetSpin, &SmokeGrenade::EventSetSpin },
|
||||
{ &EV_SmokeGrenade_SetOffset, &SmokeGrenade::EventSetOffset },
|
||||
{ &EV_SmokeGrenade_SetScale, &SmokeGrenade::EventSetScale },
|
||||
{ &EV_SmokeGrenade_SetFadein, &SmokeGrenade::EventSetFadein },
|
||||
{ &EV_SmokeGrenade_SetFadedelay, &SmokeGrenade::EventSetFadedelay },
|
||||
{ &EV_SmokeGrenade_SetMaxAlpha, &SmokeGrenade::EventSetMaxAlpha },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(EffectEntity, SmokeGrenade, "smokegrenade") {
|
||||
{&EV_SmokeGrenade_SetSpawnRate, &SmokeGrenade::EventSetSpawnrate },
|
||||
{&EV_SmokeGrenade_SetBouncefactor, &SmokeGrenade::EventSetBouncefactor},
|
||||
{&EV_SmokeGrenade_SetLife, &SmokeGrenade::EventSetLife },
|
||||
{&EV_SmokeGrenade_SetSpawnLife, &SmokeGrenade::EventSetSpawnLife },
|
||||
{&EV_SmokeGrenade_SetScalerate, &SmokeGrenade::EventSetScalerate },
|
||||
{&EV_SmokeGrenade_SetVelocity, &SmokeGrenade::EventSetVelocity },
|
||||
{&EV_SmokeGrenade_SetSpin, &SmokeGrenade::EventSetSpin },
|
||||
{&EV_SmokeGrenade_SetOffset, &SmokeGrenade::EventSetOffset },
|
||||
{&EV_SmokeGrenade_SetScale, &SmokeGrenade::EventSetScale },
|
||||
{&EV_SmokeGrenade_SetFadein, &SmokeGrenade::EventSetFadein },
|
||||
{&EV_SmokeGrenade_SetFadedelay, &SmokeGrenade::EventSetFadedelay },
|
||||
{&EV_SmokeGrenade_SetMaxAlpha, &SmokeGrenade::EventSetMaxAlpha },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void SmokeGrenade::EventSetSpawnrate(Event* ev)
|
||||
void SmokeGrenade::EventSetSpawnrate(Event *ev)
|
||||
{
|
||||
float rate = ev->GetFloat(1);
|
||||
if (rate < 0.001f) rate = 0.001f;
|
||||
if (rate < 0.001f) {
|
||||
rate = 0.001f;
|
||||
}
|
||||
|
||||
spawnRate = 1000.0f / rate;
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetBouncefactor(Event* ev)
|
||||
void SmokeGrenade::EventSetBouncefactor(Event *ev)
|
||||
{
|
||||
bounceFactor = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetLife(Event* ev)
|
||||
void SmokeGrenade::EventSetLife(Event *ev)
|
||||
{
|
||||
nextRemoveTime = level.time + ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetSpawnLife(Event* ev)
|
||||
void SmokeGrenade::EventSetSpawnLife(Event *ev)
|
||||
{
|
||||
spawnLife = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetScalerate(Event* ev)
|
||||
void SmokeGrenade::EventSetScalerate(Event *ev)
|
||||
{
|
||||
scaleRate = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetVelocity(Event* ev)
|
||||
void SmokeGrenade::EventSetVelocity(Event *ev)
|
||||
{
|
||||
velocity[0] = ev->GetFloat(1);
|
||||
velocity[1] = ev->GetFloat(2);
|
||||
velocity[2] = ev->GetFloat(3);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetSpin(Event* ev)
|
||||
void SmokeGrenade::EventSetSpin(Event *ev)
|
||||
{
|
||||
spinRate = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetOffset(Event* ev)
|
||||
void SmokeGrenade::EventSetOffset(Event *ev)
|
||||
{
|
||||
offset[0] = ev->GetFloat(1);
|
||||
offset[1] = ev->GetFloat(2);
|
||||
offset[2] = ev->GetFloat(3);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetScale(Event* ev)
|
||||
void SmokeGrenade::EventSetScale(Event *ev)
|
||||
{
|
||||
scale = ev->GetFloat(1) * 0.5;
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetFadein(Event* ev)
|
||||
void SmokeGrenade::EventSetFadein(Event *ev)
|
||||
{
|
||||
fadeIn = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetFadedelay(Event* ev)
|
||||
void SmokeGrenade::EventSetFadedelay(Event *ev)
|
||||
{
|
||||
fadeDelay = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void SmokeGrenade::EventSetMaxAlpha(Event* ev)
|
||||
void SmokeGrenade::EventSetMaxAlpha(Event *ev)
|
||||
{
|
||||
maxAlpha = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
SmokeGrenade::SmokeGrenade()
|
||||
{
|
||||
flags |= FL_THINK;
|
||||
nextRemoveTime = level.time + 1.0;
|
||||
spawnRate = 1000;
|
||||
bounceFactor = 0.0;
|
||||
spawnLife = 1.0;
|
||||
scaleRate = 1.0;
|
||||
velocity = vec_zero;
|
||||
offset = vec_zero;
|
||||
spinRate = 0.0;
|
||||
scale = 1.0;
|
||||
fadeIn = 0.0;
|
||||
fadeDelay = spawnLife;
|
||||
maxAlpha = 1.0;
|
||||
lastSpawnTime = level.inttime + 150;
|
||||
flags |= FL_THINK;
|
||||
nextRemoveTime = level.time + 1.0;
|
||||
spawnRate = 1000;
|
||||
bounceFactor = 0.0;
|
||||
spawnLife = 1.0;
|
||||
scaleRate = 1.0;
|
||||
velocity = vec_zero;
|
||||
offset = vec_zero;
|
||||
spinRate = 0.0;
|
||||
scale = 1.0;
|
||||
fadeIn = 0.0;
|
||||
fadeDelay = spawnLife;
|
||||
maxAlpha = 1.0;
|
||||
lastSpawnTime = level.inttime + 150;
|
||||
}
|
||||
|
||||
void SmokeGrenade::Think()
|
||||
@@ -233,42 +234,57 @@ void SmokeGrenade::Think()
|
||||
|
||||
if (level.inttime >= lastSpawnTime + spawnRate) {
|
||||
SmokeSprite sp;
|
||||
float degrees;
|
||||
float degrees;
|
||||
|
||||
lastSpawnTime += spawnRate;
|
||||
|
||||
sp.origin = origin;
|
||||
sp.origin = origin;
|
||||
sp.spawnTime = level.time;
|
||||
sp.scale = scale;
|
||||
sp.scale = scale;
|
||||
|
||||
degrees = angles.y + (((level.inttime / 1000.0 - 176.0) * spinRate) * -0.36);
|
||||
|
||||
RotatePointAroundAxis(
|
||||
sp.velocity,
|
||||
2,
|
||||
velocity,
|
||||
degrees
|
||||
);
|
||||
|
||||
sp.spawnLife = spawnLife;
|
||||
RotatePointAroundAxis(sp.velocity, 2, velocity, degrees);
|
||||
|
||||
sp.spawnLife = spawnLife;
|
||||
sp.bounceFactor = bounceFactor;
|
||||
sp.scaleStart = scale;
|
||||
sp.scaleRate = scaleRate;
|
||||
sp.fadeIn = fadeIn;
|
||||
sp.fadeDelay = fadeDelay;
|
||||
sp.maxAlpha = maxAlpha;
|
||||
sp.owner = owner;
|
||||
sp.scaleStart = scale;
|
||||
sp.scaleRate = scaleRate;
|
||||
sp.fadeIn = fadeIn;
|
||||
sp.fadeDelay = fadeDelay;
|
||||
sp.maxAlpha = maxAlpha;
|
||||
sp.owner = owner;
|
||||
|
||||
G_AddSmokeSprite(&sp);
|
||||
}
|
||||
}
|
||||
|
||||
void SmokeGrenade::setOwner(Sentient* other)
|
||||
void SmokeGrenade::Archive(Archiver& arc)
|
||||
{
|
||||
EffectEntity::Archive(arc);
|
||||
|
||||
arc.ArchiveFloat(&nextRemoveTime);
|
||||
arc.ArchiveInteger(&spawnRate);
|
||||
arc.ArchiveFloat(&bounceFactor);
|
||||
arc.ArchiveFloat(&spawnLife);
|
||||
arc.ArchiveFloat(&scaleRate);
|
||||
arc.ArchiveVector(&velocity);
|
||||
arc.ArchiveFloat(&spinRate);
|
||||
arc.ArchiveVector(&offset);
|
||||
arc.ArchiveFloat(&scale);
|
||||
arc.ArchiveFloat(&fadeIn);
|
||||
arc.ArchiveFloat(&fadeDelay);
|
||||
arc.ArchiveFloat(&maxAlpha);
|
||||
arc.ArchiveInteger(&lastSpawnTime);
|
||||
arc.ArchiveSafePointer(&owner);
|
||||
}
|
||||
|
||||
void SmokeGrenade::setOwner(Sentient *other)
|
||||
{
|
||||
owner = other;
|
||||
}
|
||||
|
||||
Sentient* SmokeGrenade::getOwner() const
|
||||
Sentient *SmokeGrenade::getOwner() const
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
+32
-29
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -26,43 +26,46 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
class Sentient;
|
||||
|
||||
class SmokeGrenade : public EffectEntity {
|
||||
class SmokeGrenade : public EffectEntity
|
||||
{
|
||||
CLASS_PROTOTYPE(SmokeGrenade);
|
||||
|
||||
public:
|
||||
SmokeGrenade();
|
||||
|
||||
void EventSetSpawnrate(Event* ev);
|
||||
void EventSetBouncefactor(Event* ev);
|
||||
void EventSetLife(Event* ev);
|
||||
void EventSetSpawnLife(Event* ev);
|
||||
void EventSetScalerate(Event* ev);
|
||||
void EventSetVelocity(Event* ev);
|
||||
void EventSetSpin(Event* ev);
|
||||
void EventSetOffset(Event* ev);
|
||||
void EventSetScale(Event* ev);
|
||||
void EventSetFadein(Event* ev);
|
||||
void EventSetFadedelay(Event* ev);
|
||||
void EventSetMaxAlpha(Event* ev);
|
||||
void EventSetSpawnrate(Event *ev);
|
||||
void EventSetBouncefactor(Event *ev);
|
||||
void EventSetLife(Event *ev);
|
||||
void EventSetSpawnLife(Event *ev);
|
||||
void EventSetScalerate(Event *ev);
|
||||
void EventSetVelocity(Event *ev);
|
||||
void EventSetSpin(Event *ev);
|
||||
void EventSetOffset(Event *ev);
|
||||
void EventSetScale(Event *ev);
|
||||
void EventSetFadein(Event *ev);
|
||||
void EventSetFadedelay(Event *ev);
|
||||
void EventSetMaxAlpha(Event *ev);
|
||||
|
||||
void Think() override;
|
||||
|
||||
void setOwner(Sentient* other);
|
||||
Sentient* getOwner() const;
|
||||
void Archive(Archiver& arc);
|
||||
|
||||
void setOwner(Sentient *other);
|
||||
Sentient *getOwner() const;
|
||||
|
||||
private:
|
||||
float nextRemoveTime;
|
||||
int spawnRate;
|
||||
float bounceFactor;
|
||||
float spawnLife;
|
||||
float scaleRate;
|
||||
Vector velocity;
|
||||
float spinRate;
|
||||
Vector offset;
|
||||
float scale;
|
||||
float fadeIn;
|
||||
float fadeDelay;
|
||||
float maxAlpha;
|
||||
int lastSpawnTime;
|
||||
float nextRemoveTime;
|
||||
int spawnRate;
|
||||
float bounceFactor;
|
||||
float spawnLife;
|
||||
float scaleRate;
|
||||
Vector velocity;
|
||||
float spinRate;
|
||||
Vector offset;
|
||||
float scale;
|
||||
float fadeIn;
|
||||
float fadeDelay;
|
||||
float maxAlpha;
|
||||
int lastSpawnTime;
|
||||
SafePtr<Sentient> owner;
|
||||
};
|
||||
@@ -1681,6 +1681,10 @@ void VehicleTurretGun::EndRemoteControl()
|
||||
m_iFiring = 0;
|
||||
m_vTargetAngles = m_vLocalAngles;
|
||||
|
||||
// Added in OPM
|
||||
// Clear the camera shake/jitter
|
||||
m_fCurrViewJitter = 0;
|
||||
|
||||
//
|
||||
// Added in OPM.
|
||||
// The camera must be removed after ending the remote control.
|
||||
@@ -2130,7 +2134,11 @@ void VehicleTurretGunTandem::SwitchToLinkedTurret()
|
||||
} else {
|
||||
pTurret = m_PrimaryTurret;
|
||||
// Added in 2.30
|
||||
m_PrimaryTurret->m_SwitchLabel.Execute(this, pTurret, NULL);
|
||||
if (m_PrimaryTurret) {
|
||||
// Fixed in OPM
|
||||
// Check for primary turret before setting the switch label
|
||||
m_PrimaryTurret->m_SwitchLabel.Execute(this, pTurret, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
SetActiveTurret(pTurret);
|
||||
|
||||
+39
-9
@@ -901,6 +901,16 @@ Event EV_Weapon_DoneAnimating
|
||||
EV_NORMAL
|
||||
);
|
||||
|
||||
Event EV_Weapon_GetPutaway
|
||||
(
|
||||
"putaway",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Returns whether or not the given weapon is being put away",
|
||||
EV_GETTER
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(Item, Weapon, NULL) {
|
||||
{&EV_SetAnim, &Weapon::SetWeaponAnimEvent },
|
||||
{&EV_Item_Pickup, &Weapon::PickupWeapon },
|
||||
@@ -1001,6 +1011,7 @@ CLASS_DECLARATION(Item, Weapon, NULL) {
|
||||
// Added in OPM
|
||||
//
|
||||
{&EV_Weapon_DoneAnimating, &Weapon::DoneAnimating },
|
||||
{&EV_Weapon_GetPutaway, &Weapon::EventGetPutaway },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -1238,15 +1249,9 @@ void Weapon::Delete(void)
|
||||
{
|
||||
if (g_iInThinks) {
|
||||
DetachGun();
|
||||
|
||||
if (owner) {
|
||||
RemoveFromOwner();
|
||||
}
|
||||
|
||||
PostEvent(EV_Remove, 0);
|
||||
} else {
|
||||
delete this;
|
||||
}
|
||||
|
||||
Item::Delete();
|
||||
}
|
||||
|
||||
//======================
|
||||
@@ -1640,7 +1645,6 @@ void Weapon::GetMuzzlePosition(vec3_t position, vec3_t vBarrelPos, vec3_t forwar
|
||||
int i;
|
||||
|
||||
owner = (Player *)this->owner.Pointer();
|
||||
assert(owner);
|
||||
|
||||
// We should always have an owner
|
||||
if (!owner) {
|
||||
@@ -4629,12 +4633,38 @@ Listener *Weapon::GetScriptOwner(void)
|
||||
return owner;
|
||||
}
|
||||
|
||||
//======================
|
||||
//Weapon::DoneAnimating
|
||||
//======================
|
||||
void Weapon::DoneAnimating(Event* ev) {
|
||||
// Added in OPM
|
||||
// Set to idle when done reloading
|
||||
SetWeaponIdleAnim();
|
||||
}
|
||||
|
||||
//======================
|
||||
//Weapon::GetMaxFireMovementMult
|
||||
//======================
|
||||
void Weapon::EventGetPutaway(Event* ev) {
|
||||
// Added in OPM
|
||||
// Set to idle when done reloading
|
||||
ev->AddInteger(GetPutaway());
|
||||
}
|
||||
|
||||
//======================
|
||||
//Weapon::GetMaxFireMovementMult
|
||||
//======================
|
||||
float Weapon::GetMaxFireMovementMult() const {
|
||||
return m_fMaxFireMovement * m_fMovementSpeed;
|
||||
}
|
||||
|
||||
//======================
|
||||
//Weapon::GetMaxFireMovementMult
|
||||
//======================
|
||||
float Weapon::GetZoomMovement() const {
|
||||
return m_fZoomMovement * m_fMovementSpeed;
|
||||
}
|
||||
|
||||
//======================
|
||||
//Weapon::GetMaxFireMovement
|
||||
//======================
|
||||
|
||||
@@ -460,7 +460,10 @@ public:
|
||||
firemode_t GetFireMode(void);
|
||||
qboolean IsSemiAuto(void);
|
||||
void DoneAnimating(Event *ev);
|
||||
void EventGetPutaway(Event *ev);
|
||||
|
||||
float GetMaxFireMovementMult() const;
|
||||
float GetZoomMovement() const;
|
||||
float GetMaxFireMovement() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
include_directories("./common")
|
||||
include_directories("./gcdkey")
|
||||
|
||||
@@ -96,7 +96,7 @@ void gsDebugAssert (const char *szError,const char *szText, const char *szFi
|
||||
// continues rendering
|
||||
void _gsDebugAssert (const char *string)
|
||||
{
|
||||
printf(string);
|
||||
printf("%s", string);
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ void gsDebugAssert (const char *szError,const char *szText, const char *szFi
|
||||
void _gsDebugAssert (const char *string)
|
||||
{
|
||||
|
||||
scePrintf(string);
|
||||
scePrintf("%s", string);
|
||||
while(1);;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void gsDebugAssert (const char *szError,const char *szText, const char *szFi
|
||||
#elif defined _MACOSX
|
||||
void _gsDebugAssert (const char *string)
|
||||
{
|
||||
printf(string);
|
||||
printf("%s", string);
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -139,7 +139,7 @@ void gsDebugAssert (const char *szError,const char *szText, const char *szFi
|
||||
#elif defined _LINUX
|
||||
void _gsDebugAssert (const char *string)
|
||||
{
|
||||
printf(string);
|
||||
printf("%s", string);
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -170,7 +170,7 @@ void gsDebugAssert (const char *szError,const char *szText, const char *szFi
|
||||
void _gsDebugAssert (const char *string)
|
||||
{
|
||||
|
||||
printf(string);
|
||||
printf("%s", string);
|
||||
while(1);;
|
||||
|
||||
}
|
||||
|
||||
@@ -62,6 +62,9 @@ void CL_CharEvent( int key ) {
|
||||
void CL_Disconnect() {
|
||||
}
|
||||
|
||||
void CL_AbnormalDisconnect() {
|
||||
}
|
||||
|
||||
void CL_MapLoading( qboolean flush, const char *pszMapName ) {
|
||||
}
|
||||
|
||||
@@ -129,3 +132,7 @@ qboolean CL_FinishedIntro( void ) {
|
||||
int R_CountTextureMemory() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qboolean CL_UseLargeLightmap(const char* mapName) {
|
||||
return qtrue;
|
||||
}
|
||||
@@ -103,7 +103,6 @@ int success_pos;
|
||||
%left TOKEN_DOUBLE_COLON
|
||||
%left TOKEN_SEMICOLON
|
||||
%right TOKEN_DOLLAR
|
||||
%left TOKEN_NUMBER
|
||||
|
||||
%token TOKEN_INCREMENT TOKEN_DECREMENT TOKEN_PERIOD
|
||||
|
||||
|
||||
+23
-10
@@ -190,6 +190,8 @@ static bool UseField( void )
|
||||
|
||||
string ([^\\\"\r\n]|\\.)*
|
||||
identifier [^\{\}\(\)\[\]\r\n\,:; \t]
|
||||
nonexpr [0-9a-zA-Z_\"'?@#`\.\x80-\xff]
|
||||
nonnumeric [a-zA-Z_\"'?@#`\x80-\xff]
|
||||
alphanum [a-zA-Z0-9_]+
|
||||
varname [a-zA-Z0-9_\"\$]+
|
||||
|
||||
@@ -205,7 +207,7 @@ varname [a-zA-Z0-9_\"\$]+
|
||||
"//"[^\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); }
|
||||
|
||||
<VARIABLES>"size" { BEGIN(INITIAL); YYLEX(TOKEN_SIZE); }
|
||||
<VARIABLES>[ ]*\./([0-9]*[^0-9[:space:]]) { YYLEX(TOKEN_PERIOD); }
|
||||
<VARIABLES>[ \t]*\./([0-9]*[^0-9[:space:]]) { YYLEX(TOKEN_PERIOD); }
|
||||
<VARIABLES>\"{string}\" { BEGIN(INITIAL); TextEscapeValue(yytext + 1, strlen( yytext ) - 2 ); YYLEX(TOKEN_STRING); }
|
||||
<VARIABLES>{varname} {
|
||||
TextValue(yytext, strlen(yytext));
|
||||
@@ -221,9 +223,15 @@ varname [a-zA-Z0-9_\"\$]+
|
||||
unput(yytext[yyleng - 1]);
|
||||
yyreducepos(1);
|
||||
}
|
||||
|
||||
\"{string}\" { TextEscapeValue( yytext + 1, yyleng - 2 ); YYLEX( TOKEN_STRING ); }
|
||||
|
||||
|
||||
|
||||
\"{string}\"{nonexpr} {
|
||||
BEGIN(IDENTIFIER);
|
||||
yymore();
|
||||
}
|
||||
|
||||
\"{string}\" { TextEscapeValue( yytext + 1, yyleng - 2 ); YYLEX( TOKEN_STRING ); }
|
||||
|
||||
"?" { YYLEX( TOKEN_TERNARY ); }
|
||||
"if" { YYLEX( TOKEN_IF ); }
|
||||
@@ -264,15 +272,15 @@ varname [a-zA-Z0-9_\"\$]+
|
||||
">" { YYLEX( TOKEN_GREATER_THAN ); }
|
||||
"<=" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); }
|
||||
">=" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); }
|
||||
[ ]"-" { YYLEX( TOKEN_NEG ); }
|
||||
[ \t]"-" { YYLEX( TOKEN_NEG ); }
|
||||
|
||||
"+" { YYLEX( TOKEN_PLUS ); }
|
||||
"+=" { YYLEX( TOKEN_PLUS_EQUALS ); }
|
||||
"++"|[ ]"++" { YYLEX( TOKEN_INCREMENT ); }
|
||||
"-"|"-"[ ]|[ ]"-"[ ] { YYLEX( TOKEN_MINUS ); }
|
||||
"++"|[ \t]"++" { YYLEX( TOKEN_INCREMENT ); }
|
||||
"-"|"-"[ \t]|[ \t]"-"[ \t] { YYLEX( TOKEN_MINUS ); }
|
||||
"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
|
||||
[ ]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
|
||||
"--"|[ ]"--" { YYLEX( TOKEN_DECREMENT ); }
|
||||
[ \t]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
|
||||
"--"|[ \t]"--" { YYLEX( TOKEN_DECREMENT ); }
|
||||
"*" { YYLEX( TOKEN_MULTIPLY ); }
|
||||
"*=" { YYLEX( TOKEN_MULTIPLY_EQUALS ); }
|
||||
"/" { YYLEX( TOKEN_DIVIDE ); }
|
||||
@@ -293,7 +301,6 @@ varname [a-zA-Z0-9_\"\$]+
|
||||
"." { YYLEX( TOKEN_PERIOD ); }
|
||||
|
||||
"," { YYLEX( TOKEN_COMMA ); }
|
||||
"#" { YYLEX( TOKEN_NUMBER ); }
|
||||
|
||||
"NULL" { YYLEX( TOKEN_NULL ); }
|
||||
"NIL" { YYLEX( TOKEN_NIL ); }
|
||||
@@ -312,11 +319,17 @@ varname [a-zA-Z0-9_\"\$]+
|
||||
[\r\n]+ { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); }
|
||||
[ \t] { ; }
|
||||
|
||||
[0-9^`]+ {
|
||||
[0-9]+ {
|
||||
char* p = nullptr;
|
||||
yylval.s.val.intValue = std::strtol(yytext, &p, 10);
|
||||
YYLEX(TOKEN_INTEGER);
|
||||
}
|
||||
|
||||
[0-9\.]+{nonnumeric} {
|
||||
BEGIN(IDENTIFIER);
|
||||
yymore();
|
||||
}
|
||||
|
||||
[0-9\.]+|[0-9\.]+("e+"|"e-")+[0-9\.] {
|
||||
char* p = nullptr;
|
||||
yylval.s.val.floatValue = std::strtof(yytext, &p);
|
||||
|
||||
+22
-11
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(qcommon)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.12")
|
||||
@@ -8,7 +9,7 @@ endif()
|
||||
include("./q_version.cmake")
|
||||
|
||||
# Shared source files for modules
|
||||
set(SOURCES_SHARED
|
||||
set(SOURCES_SHARED_UBER
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/class.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/con_set.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/con_timer.cpp"
|
||||
@@ -17,25 +18,35 @@ set(SOURCES_SHARED
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/lz77.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/mem_blockalloc.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/mem_tempalloc.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/q_math.c"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/q_shared.c"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/script.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/str.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/script/scriptexception.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/script/scriptvariable.cpp"
|
||||
)
|
||||
|
||||
add_library(qcommon INTERFACE)
|
||||
target_sources(qcommon INTERFACE ${SOURCES_SHARED})
|
||||
add_library(qcommon_uber INTERFACE)
|
||||
target_sources(qcommon_uber INTERFACE ${SOURCES_SHARED_UBER})
|
||||
target_compile_features(qcommon_uber INTERFACE cxx_nullptr)
|
||||
target_include_directories(qcommon_uber INTERFACE "../qcommon" "../script")
|
||||
|
||||
if(DEBUG_MEM_BLOCK)
|
||||
target_compile_definitions(qcommon INTERFACE _DEBUG_MEMBLOCK=1)
|
||||
target_compile_definitions(qcommon_uber INTERFACE _DEBUG_MEMBLOCK=1)
|
||||
endif()
|
||||
|
||||
target_include_directories(qcommon INTERFACE "../qcommon" "../script")
|
||||
target_compile_features(qcommon INTERFACE cxx_nullptr)
|
||||
target_compile_features(qcommon INTERFACE c_variadic_macros)
|
||||
target_link_libraries(qcommon INTERFACE qcommon_version)
|
||||
set(SOURCES_SHARED
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/puff.c"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/q_math.c"
|
||||
"${CMAKE_SOURCE_DIR}/code/qcommon/q_shared.c"
|
||||
)
|
||||
|
||||
add_library(qcommon_shared INTERFACE)
|
||||
target_sources(qcommon_shared INTERFACE ${SOURCES_SHARED})
|
||||
target_compile_features(qcommon_shared INTERFACE c_variadic_macros)
|
||||
target_include_directories(qcommon_shared INTERFACE "../qcommon")
|
||||
target_link_libraries(qcommon_shared INTERFACE qcommon_version)
|
||||
|
||||
add_library(qcommon INTERFACE)
|
||||
target_link_libraries(qcommon INTERFACE qcommon_shared qcommon_uber)
|
||||
|
||||
# Source files for standalone executable
|
||||
set(SOURCES_COMMON
|
||||
|
||||
+501
-604
File diff suppressed because it is too large.
Load diff
@@ -766,6 +766,10 @@ static qboolean CM_ValidateFacet( facet_t *facet ) {
|
||||
Vector4Copy( planes[ facet->surfacePlane ].plane, plane );
|
||||
w = BaseWindingForPlane( plane, plane[3] );
|
||||
for ( j = 0 ; j < facet->numBorders && w ; j++ ) {
|
||||
if ( facet->borderPlanes[j] == -1 ) {
|
||||
FreeWinding( w );
|
||||
return qfalse;
|
||||
}
|
||||
Vector4Copy( planes[ facet->borderPlanes[j] ].plane, plane );
|
||||
if ( !facet->borderInward[j] ) {
|
||||
VectorSubtract( vec3_origin, plane, plane );
|
||||
@@ -783,7 +787,7 @@ static qboolean CM_ValidateFacet( facet_t *facet ) {
|
||||
FreeWinding( w );
|
||||
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( bounds[1][j] - bounds[0][j] > MAX_MAP_BOUNDS ) {
|
||||
if ( bounds[1][j] - bounds[0][j] > MAP_SIZE ) {
|
||||
return qfalse; // we must be missing a plane
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,10 @@ properly.
|
||||
|
||||
|
||||
#define MAX_FACETS 1024
|
||||
#define MAX_PATCH_PLANES 4096 // 2048 su44: increased for m1l2a
|
||||
// Changed in OPM
|
||||
// In OG it's 4096, however due to a tiny floating point difference
|
||||
// between x86 and x64, more patch planes can appear in x64
|
||||
#define MAX_PATCH_PLANES 6144
|
||||
|
||||
typedef struct {
|
||||
float plane[4];
|
||||
|
||||
@@ -160,8 +160,8 @@ void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs)
|
||||
vec_t v;
|
||||
int i,j;
|
||||
|
||||
mins[0] = mins[1] = mins[2] = MAX_MAP_BOUNDS;
|
||||
maxs[0] = maxs[1] = maxs[2] = -MAX_MAP_BOUNDS;
|
||||
mins[0] = mins[1] = mins[2] = 99999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -99999;
|
||||
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
@@ -208,7 +208,7 @@ winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist)
|
||||
|
||||
// find the major axis
|
||||
|
||||
max = -MAX_MAP_BOUNDS;
|
||||
max = -MAP_SIZE;
|
||||
x = -1;
|
||||
for (i=0 ; i<3; i++)
|
||||
{
|
||||
@@ -242,8 +242,8 @@ winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist)
|
||||
|
||||
CrossProduct (vup, normal, vright);
|
||||
|
||||
VectorScale (vup, MAX_MAP_BOUNDS, vup);
|
||||
VectorScale (vright, MAX_MAP_BOUNDS, vright);
|
||||
VectorScale (vup, MAP_SIZE, vup);
|
||||
VectorScale (vright, MAP_SIZE, vright);
|
||||
|
||||
// project a really big axis aligned box onto the plane
|
||||
w = AllocWinding (4);
|
||||
@@ -564,7 +564,7 @@ void CheckWinding (winding_t *w)
|
||||
p1 = w->p[i];
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
if (p1[j] > MAX_MAP_BOUNDS || p1[j] < -MAX_MAP_BOUNDS)
|
||||
if (p1[j] > MAP_SIZE || p1[j] < -MAP_SIZE)
|
||||
Com_Error (ERR_DROP, "CheckFace: BUGUS_RANGE: %f",p1[j]);
|
||||
|
||||
j = i+1 == w->numpoints ? 0 : i+1;
|
||||
|
||||
+2
-2
@@ -667,7 +667,7 @@ static void Cmd_TokenizeString2( const char *text_in, qboolean ignoreQuotes ) {
|
||||
|
||||
while ( 1 ) {
|
||||
// skip whitespace
|
||||
while ( *text && *text <= ' ' ) {
|
||||
while ( *text && ( unsigned char )*text <= ' ' ) {
|
||||
text++;
|
||||
}
|
||||
if ( !*text ) {
|
||||
@@ -715,7 +715,7 @@ static void Cmd_TokenizeString2( const char *text_in, qboolean ignoreQuotes ) {
|
||||
cmd_argc++;
|
||||
|
||||
// skip until whitespace, quote, or command
|
||||
while ( *text > ' ' ) {
|
||||
while ( ( unsigned char )*text > ' ' ) {
|
||||
if ( !ignoreQuotes && text[0] == '"' ) {
|
||||
break;
|
||||
}
|
||||
|
||||
+68
-29
@@ -419,30 +419,40 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
|
||||
Cvar_Set("com_errorMessage", com_errorMessage);
|
||||
|
||||
if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
|
||||
CL_Disconnect();
|
||||
CL_FlushMemory( );
|
||||
if (com_cl_running && com_cl_running->integer) {
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
} else {
|
||||
SV_Shutdown(va("Server disconnected: %s", com_errorMessage));
|
||||
}
|
||||
// make sure we can get at our local stuff
|
||||
FS_PureServerSetLoadedPaks("", "");
|
||||
com_errorEntered = qfalse;
|
||||
longjmp (abortframe, -1);
|
||||
} else if (code == ERR_DROP) {
|
||||
Com_Printf ("********************\nERROR: %s\n********************\n", com_errorMessage);
|
||||
SV_Shutdown (va("Server crashed: %s", com_errorMessage));
|
||||
CL_Disconnect();
|
||||
CL_FlushMemory( );
|
||||
SV_Shutdown(va("Server crashed: %s", com_errorMessage));
|
||||
#ifndef DEDICATED
|
||||
if (com_cl_running && com_cl_running->integer) {
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
}
|
||||
#endif
|
||||
FS_PureServerSetLoadedPaks("", "");
|
||||
com_errorEntered = qfalse;
|
||||
longjmp (abortframe, -1);
|
||||
} else if ( code == ERR_NEED_CD ) {
|
||||
SV_Shutdown( "Server didn't have CD" );
|
||||
if ( com_cl_running && com_cl_running->integer ) {
|
||||
CL_Disconnect();
|
||||
CL_FlushMemory( );
|
||||
com_errorEntered = qfalse;
|
||||
CL_CDDialog();
|
||||
} else {
|
||||
Com_Printf("Server didn't have CD\n" );
|
||||
}
|
||||
SV_Shutdown("Server didn't have CD");
|
||||
if (com_cl_running && com_cl_running->integer) {
|
||||
CL_Disconnect();
|
||||
CL_FlushMemory();
|
||||
com_errorEntered = qfalse;
|
||||
CL_CDDialog();
|
||||
} else {
|
||||
Com_Printf("Server didn't have CD\n");
|
||||
}
|
||||
FS_PureServerSetLoadedPaks("", "");
|
||||
longjmp (abortframe, -1);
|
||||
} else {
|
||||
@@ -1602,6 +1612,22 @@ static void Com_InitRand(void)
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Com_ConfigExists
|
||||
=================
|
||||
*/
|
||||
qboolean Com_ConfigExists(const char* configname) {
|
||||
fileHandle_t handle = (fileHandle_t)0;
|
||||
|
||||
if (FS_FOpenFileRead(va("configs/%s", configname), &handle, qfalse, qfalse) == -1) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
FS_FCloseFile(handle);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Com_Init
|
||||
@@ -1676,7 +1702,9 @@ void Com_Init( char *commandLine ) {
|
||||
|
||||
Cbuf_AddText( "exec menu.cfg\n" );
|
||||
|
||||
Cbuf_AddText ("exec newconfig.cfg\n");
|
||||
// Removed in OPM
|
||||
// Not relevant as there is no auto-configurator
|
||||
//Cbuf_AddText ("exec newconfig.cfg\n");
|
||||
|
||||
cvar_global_force = qtrue;
|
||||
Cbuf_Execute( 0 );
|
||||
@@ -1689,27 +1717,33 @@ void Com_Init( char *commandLine ) {
|
||||
|
||||
config = Cvar_Get( "config", "omconfig.cfg", 0 );
|
||||
|
||||
if( strlen( config->string ) <= 1 )
|
||||
if( strlen( config->string ) > 1 )
|
||||
{
|
||||
size_t len = strlen( config->string );
|
||||
|
||||
Q_strncpyz( configname, config->string, len >= sizeof( configname ) ? sizeof( configname ) : len );
|
||||
COM_StripExtension( configname, configname, sizeof( configname ) );
|
||||
Q_strcat( configname, sizeof( configname ), ".cfg" );
|
||||
SaveRegistryInfo( 1, "config", configname, sizeof( configname ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
long size = sizeof( configname );
|
||||
LoadRegistryInfo(1, "config", configname, &size );
|
||||
COM_DefaultExtension( configname, sizeof( configname ), ".cfg" );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = strlen( config->string );
|
||||
|
||||
strncpy( configname, config->string, len >= sizeof( configname ) ? sizeof( configname ) : len );
|
||||
COM_StripExtension( configname, configname, sizeof( configname ) );
|
||||
strcat( configname, ".cfg" );
|
||||
SaveRegistryInfo( 1, "config", configname, sizeof( configname ) );
|
||||
}
|
||||
|
||||
SaveRegistryInfo( 1, "config", configname, sizeof( configname ) );
|
||||
|
||||
Cvar_Set( "config", configname );
|
||||
Com_Printf( "Config: %s\n", configname );
|
||||
|
||||
Cbuf_AddText( va( "exec configs/%s\n", configname ) );
|
||||
if ( !Com_ConfigExists( configname )) {
|
||||
Com_Printf( "The config file '%s' doesn't exist, using unnamedsoldier.cfg as a template\n", configname );
|
||||
Cbuf_AddText( va( "exec configs/unnamedsoldier.cfg\n", configname ) );
|
||||
} else {
|
||||
Cbuf_AddText( va( "exec configs/%s\n", configname ) );
|
||||
}
|
||||
|
||||
if( Com_SafeMode() )
|
||||
{
|
||||
@@ -1829,7 +1863,9 @@ void Com_Init( char *commandLine ) {
|
||||
|
||||
Sys_Init();
|
||||
|
||||
//Sys_InitPIDFile(FS_GetCurrentGameDir());
|
||||
#ifdef NDEBUG
|
||||
Sys_InitPIDFile(FS_GetCurrentGameDir());
|
||||
#endif
|
||||
|
||||
// Pick a random port value
|
||||
Com_RandomBytes((byte*)&qport, sizeof(int));
|
||||
@@ -2370,11 +2406,14 @@ void Com_Shutdown (void) {
|
||||
|
||||
}
|
||||
|
||||
qboolean Com_SanitizeName( const char *pszOldName, char *pszNewName )
|
||||
qboolean Com_SanitizeName( const char *pszOldName, char *pszNewName, size_t bufferSize )
|
||||
{
|
||||
int i;
|
||||
qboolean bBadName = qfalse;
|
||||
const char *p = pszOldName;
|
||||
size_t maxLength;
|
||||
|
||||
maxLength = (bufferSize / sizeof(char)) - 1;
|
||||
|
||||
if( *pszOldName && *pszOldName <= ' ' )
|
||||
{
|
||||
@@ -2387,7 +2426,7 @@ qboolean Com_SanitizeName( const char *pszOldName, char *pszNewName )
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for( i = 0; *p && *p >= ' '; p++, i++ )
|
||||
for( i = 0; *p && *p >= ' ' && i < maxLength; p++, i++ )
|
||||
{
|
||||
if( *p == '~' || *p == '`' )
|
||||
{
|
||||
|
||||
+13
-3
@@ -2367,6 +2367,9 @@ char **FS_ListFilteredFiles( const char *path, const char *extension, const char
|
||||
}
|
||||
|
||||
pathLength = strlen( path );
|
||||
if ( path[pathLength-1] == '\\' || path[pathLength-1] == '/' ) {
|
||||
pathLength--;
|
||||
}
|
||||
extensionLength = strlen( extension );
|
||||
nfiles = 0;
|
||||
FS_ReturnPath(path, zpath, &pathDepth);
|
||||
@@ -2445,13 +2448,18 @@ char **FS_ListFilteredFiles( const char *path, const char *extension, const char
|
||||
}
|
||||
// unique the match
|
||||
|
||||
temp = pathLength;
|
||||
if (pathLength) {
|
||||
temp++; // include the '/'
|
||||
}
|
||||
|
||||
if (bDirSearch) {
|
||||
strcpy(zpath, name + pathLength);
|
||||
zpath[length - pathLength - 1] = 0;
|
||||
strcpy(zpath, name + temp);
|
||||
zpath[length - temp - 1] = 0;
|
||||
nfiles = FS_AddFileToList(zpath, list, nfiles);
|
||||
}
|
||||
else {
|
||||
nfiles = FS_AddFileToList(name + pathLength, list, nfiles);
|
||||
nfiles = FS_AddFileToList(name + temp, list, nfiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4004,7 +4012,9 @@ void FS_Restart( int checksumFeed ) {
|
||||
// try to start up normally
|
||||
FS_Startup(com_basegame->string);
|
||||
|
||||
#ifndef STANDALONE
|
||||
FS_CheckPak0( );
|
||||
#endif
|
||||
|
||||
// if we can't find default.cfg, assume that the paths are
|
||||
// busted and error out now, rather than getting an unreadable
|
||||
|
||||
@@ -73,7 +73,8 @@ EventQueueNode Event::EventQueue;
|
||||
|
||||
int DisableListenerNotify = 0;
|
||||
|
||||
bool Listener::EventSystemStarted = 0;
|
||||
bool Listener::EventSystemStarted = false;
|
||||
bool Listener::ProcessingEvents = false;
|
||||
|
||||
Event EV_Listener_CancelFor
|
||||
(
|
||||
@@ -575,6 +576,8 @@ void L_ProcessPendingEvents()
|
||||
{
|
||||
EventQueueNode *node;
|
||||
|
||||
Listener::ProcessingEvents = true;
|
||||
|
||||
int t = EVENT_msec;
|
||||
while (!LL_Empty(&Event::EventQueue, next, prev)) {
|
||||
Listener *obj;
|
||||
@@ -600,6 +603,8 @@ void L_ProcessPendingEvents()
|
||||
|
||||
delete node;
|
||||
}
|
||||
|
||||
Listener::ProcessingEvents = false;
|
||||
}
|
||||
|
||||
void L_ShutdownEvents(void)
|
||||
@@ -3007,6 +3012,8 @@ qboolean Listener::ProcessPendingEvents(void)
|
||||
|
||||
t = EVENT_msec;
|
||||
|
||||
Listener::ProcessingEvents = true;
|
||||
|
||||
event = Event::EventQueue.next;
|
||||
while (event != &Event::EventQueue) {
|
||||
Listener *obj;
|
||||
@@ -3039,6 +3046,8 @@ qboolean Listener::ProcessPendingEvents(void)
|
||||
}
|
||||
}
|
||||
|
||||
Listener::ProcessingEvents = false;
|
||||
|
||||
return processedEvents;
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 315 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user