mirror of
https://github.com/yquake2/ctf.git
synced 2025-04-20 17:43:18 +00:00
Compare commits
81 commits
Author | SHA1 | Date | |
---|---|---|---|
|
3a1863f625 | ||
|
c7a4b27bf6 | ||
|
8878216828 | ||
|
dcc5a1f616 | ||
|
869b18c329 | ||
|
0a7e3c9c78 | ||
|
693e82ffa4 | ||
|
b9cac9410e | ||
|
787de54da5 | ||
|
6a2d5125f6 | ||
|
b8a45290a2 | ||
|
38cc7813dd | ||
|
a5f933ba03 | ||
|
95852c466c | ||
|
4bbda4cd98 | ||
|
48c30c68a3 | ||
|
c99c53d4b6 | ||
|
554590fca9 | ||
|
ab58bc5a37 | ||
|
606a52ddf4 | ||
|
7932c76d16 | ||
|
55b80715ac | ||
|
2e2e1945e8 | ||
|
5e4fc5a0ed | ||
|
72b78e39ca | ||
|
ff3a920d20 | ||
|
5f7038c407 | ||
|
928066d37d | ||
|
f31b3264d5 | ||
|
23d0f705c6 | ||
|
26019096ee | ||
|
1531bcebb7 | ||
|
fad0152c6b | ||
|
8e92749a8b | ||
|
16198d78be | ||
|
befa16b12f | ||
|
71574de589 | ||
|
2ffb440a66 | ||
|
d209850ef7 | ||
|
cf0471a367 | ||
|
8c58273867 | ||
|
4f8b49daf3 | ||
|
821872c798 | ||
|
15a25d8daa | ||
|
0e35097cd0 | ||
|
d7457925db | ||
|
c13036df55 | ||
|
08a9c4fdc1 | ||
|
1e37bf132d | ||
|
2d6dd4117d | ||
|
b67a392cb6 | ||
|
f5449a9185 | ||
|
3e82fe1ef2 | ||
|
097dd56e35 | ||
|
ca0e44b2a4 | ||
|
5447354a76 | ||
|
6f1b2f101f | ||
|
327cea19f5 | ||
|
df29a29633 | ||
|
b475a527c9 | ||
|
eadb063611 | ||
|
d8d33d4353 | ||
|
b71b80d790 | ||
|
8439d43508 | ||
|
adb307b197 | ||
|
8cef59c4c8 | ||
|
a089f4c747 | ||
|
8a40cd5e9f | ||
|
0516300a11 | ||
|
36ed53346e | ||
|
70c9889d16 | ||
|
445f266843 | ||
|
ee24659ba4 | ||
|
a65b93192c | ||
|
dffca8fc79 | ||
|
988afce481 | ||
|
e2b397d92c | ||
|
ca84136e65 | ||
|
017bc7276f | ||
|
5caf9c980f | ||
|
6286419315 |
29 changed files with 872 additions and 277 deletions
45
.github/workflows/linux_aarch64.yml
vendored
Normal file
45
.github/workflows/linux_aarch64.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
name: Testbuild for Linux (aarch64)
|
||||
run-name: testbuild_linux_aarch64
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_aarch64:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-ctf-linux_aarch64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-ctf-linux_aarch64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp LICENSE publish/quake2-ctf-linux_aarch64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-ctf-linux_aarch64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-ctf-linux_aarch64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
45
.github/workflows/linux_x86_64.yml
vendored
Normal file
45
.github/workflows/linux_x86_64.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
name: Testbuild for Linux (x86_64)
|
||||
run-name: testbuild_linux_x86_64
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_x86_64:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-ctf-linux_x86_64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-ctf-linux_x86_64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp LICENSE publish/quake2-ctf-linux_x86_64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-ctf-linux_x86_64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-ctf-linux_x86_64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
49
.github/workflows/macos.yml
vendored
Normal file
49
.github/workflows/macos.yml
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
name: Testbuild for MacOS
|
||||
run-name: testbuild_macos
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_macos_aarch64:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: macos
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install make
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# Public runners come with 3 CPUs.
|
||||
gmake -j3
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-ctf-macos-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-ctf-macos-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp LICENSE publish/quake2-ctf-macos-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-ctf-macos-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-ctf-macos-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
56
.github/workflows/win32.yml
vendored
Normal file
56
.github/workflows/win32.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
name: Testbuild for Win32
|
||||
run-name: testbuild_win32
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_mingw_x86_32:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { sys: mingw32, env: i686 }
|
||||
steps:
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{matrix.sys}}
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-${{matrix.env}}-gcc
|
||||
mingw-w64-${{matrix.env}}-make
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
- name: Create testbuild package
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-ctf-win32-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-ctf-win32-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp LICENSE publish/quake2-ctf-win32-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-ctf-win32-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-ctf-win32-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
56
.github/workflows/win64.yml
vendored
Normal file
56
.github/workflows/win64.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
name: Testbuild for Win64
|
||||
run-name: testbuild_win64
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_mingw_x86_64:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { sys: mingw64, env: x86_64 }
|
||||
steps:
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{matrix.sys}}
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-${{matrix.env}}-gcc
|
||||
mingw-w64-${{matrix.env}}-make
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
- name: Create testbuild package
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-ctf-win64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-ctf-win64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp LICENSE publish/quake2-ctf-win64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-ctf-win64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-ctf-win64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
build/
|
||||
release/
|
32
CHANGELOG
32
CHANGELOG
|
@ -1,3 +1,35 @@
|
|||
Three Wave Capture The Flag 1.10 to 1.11
|
||||
- Fix build in C23 mode.
|
||||
|
||||
Three Wave Capture The Flag 1.09 to 1.10
|
||||
- Fix build on ARM Macs.
|
||||
|
||||
Three Wave Capture The Flag 1.08 to 1.09
|
||||
- Several small bugfixes.
|
||||
|
||||
Three Wave Capture The Flag 1.07 to 1.08
|
||||
- Several small bugfixes.
|
||||
|
||||
Three Wave Capture The Flag 1.06 to 1.07
|
||||
- Several small bugfixes.
|
||||
|
||||
Three Wave Capture The Flag 1.05 to 1.06
|
||||
- Small bugfixes.
|
||||
- Better compatibility with the current Windows build environment.
|
||||
|
||||
Three Wave Capture The Flag 1.04 to 1.05
|
||||
- Some bugfixes to monster AI, mostly to keep the source
|
||||
in sync with baseq2 and the other addons.
|
||||
|
||||
Three Wave Capture The Flag 1.03 to 1.04
|
||||
- Fix CMake support
|
||||
- Make gibs and debris SOLID_BBOX so they move on entities.
|
||||
- Switch from an arch whitelist to an "all archs are supported"
|
||||
approach.
|
||||
|
||||
Three Wave Capture The Flag 1.02 to 1.03
|
||||
- Add CMake as an optional build system.
|
||||
- Fix bug with high velocities in vents in 32bit builds.
|
||||
|
||||
Three Wave Capture The Flag 1.01 to 1.02
|
||||
- Port "Three Wave Capture The Flag" to Mac OS X
|
||||
|
|
76
CMakeLists.txt
Normal file
76
CMakeLists.txt
Normal file
|
@ -0,0 +1,76 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Print a message that using the Makefiles is recommended.
|
||||
message(NOTICE: " The CMakeLists.txt is unmaintained. Use the Makefile if possible.")
|
||||
|
||||
# Enforce "Debug" as standard build type
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# CMake project configuration
|
||||
project(yquake2-ctf)
|
||||
|
||||
# Enforce compiler flags (GCC / Clang compatible, yquake2
|
||||
# won't build with another compiler anyways)
|
||||
# -Wall -> More warnings
|
||||
# -fno-strict-aliasing -> Quake 2 is far away from strict aliasing
|
||||
# -fwrapv -> Make signed integer overflows defined
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fno-strict-aliasing -fwrapv")
|
||||
|
||||
# Use -O2 as maximum optimization level. -O3 has it's problems with yquake2.
|
||||
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
|
||||
# Linker Flags
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
list(APPEND CtfLinkerFlags "-lm")
|
||||
else()
|
||||
list(APPEND CtfLinkerFlags "-lm -rdynamic")
|
||||
endif()
|
||||
|
||||
set(Ctf-Source
|
||||
src/menu/menu.c
|
||||
src/monster/move.c
|
||||
src/player/client.c
|
||||
src/player/hud.c
|
||||
src/player/trail.c
|
||||
src/player/view.c
|
||||
src/player/weapon.c
|
||||
src/shared/shared.c
|
||||
src/g_ai.c
|
||||
src/g_chase.c
|
||||
src/g_cmds.c
|
||||
src/g_combat.c
|
||||
src/g_ctf.c
|
||||
src/g_func.c
|
||||
src/g_items.c
|
||||
src/g_main.c
|
||||
src/g_misc.c
|
||||
src/g_monster.c
|
||||
src/g_phys.c
|
||||
src/g_save.c
|
||||
src/g_spawn.c
|
||||
src/g_svcmds.c
|
||||
src/g_target.c
|
||||
src/g_trigger.c
|
||||
src/g_utils.c
|
||||
src/g_weapon.c
|
||||
)
|
||||
|
||||
set(Ctf-Header
|
||||
src/header/ctf.h
|
||||
src/header/game.h
|
||||
src/header/local.h
|
||||
src/header/menu.h
|
||||
src/header/shared.h
|
||||
src/monster/player.h
|
||||
)
|
||||
|
||||
# Build the ctf dynamic library
|
||||
add_library(game SHARED ${Ctf-Source} ${Ctf-Header})
|
||||
set_target_properties(game PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release
|
||||
)
|
||||
target_link_libraries(game ${CtfLinkerFlags})
|
213
Makefile
Normal file → Executable file
213
Makefile
Normal file → Executable file
|
@ -6,72 +6,161 @@
|
|||
# #
|
||||
# Dependencies: #
|
||||
# - None, but you need a Quake II to play. #
|
||||
# While in theorie every one should work #
|
||||
# Yamagi Quake II ist recommended. #
|
||||
# While in theory every one should work #
|
||||
# Yamagi Quake II is recommended. #
|
||||
# #
|
||||
# Platforms: #
|
||||
# - FreeBSD #
|
||||
# - Linux #
|
||||
# - Mac OS X #
|
||||
# - OpenBSD #
|
||||
# - Windows #
|
||||
# ----------------------------------------------------- #
|
||||
|
||||
# Detect the OS
|
||||
ifdef SystemRoot
|
||||
OSTYPE := Windows
|
||||
YQ2_OSTYPE ?= Windows
|
||||
else
|
||||
OSTYPE := $(shell uname -s)
|
||||
YQ2_OSTYPE ?= $(shell uname -s)
|
||||
endif
|
||||
|
||||
# Special case for MinGW
|
||||
ifneq (,$(findstring MINGW,$(YQ2_OSTYPE)))
|
||||
YQ2_OSTYPE := Windows
|
||||
endif
|
||||
|
||||
# Detect the architecture
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
# At this time only i386 is supported on Windows
|
||||
ARCH := i386
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
ifdef MINGW_CHOST
|
||||
ifeq ($(MINGW_CHOST), x86_64-w64-mingw32)
|
||||
YQ2_ARCH ?= x86_64
|
||||
else # i686-w64-mingw32
|
||||
YQ2_ARCH ?= i386
|
||||
endif
|
||||
else # windows, but MINGW_CHOST not defined
|
||||
ifdef PROCESSOR_ARCHITEW6432
|
||||
# 64 bit Windows
|
||||
YQ2_ARCH ?= $(PROCESSOR_ARCHITEW6432)
|
||||
else
|
||||
# Some platforms call it "amd64" and some "x86_64"
|
||||
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/amd64/x86_64/)
|
||||
# 32 bit Windows
|
||||
YQ2_ARCH ?= $(PROCESSOR_ARCHITECTURE)
|
||||
endif
|
||||
endif # windows but MINGW_CHOST not defined
|
||||
else
|
||||
ifneq ($(YQ2_OSTYPE), Darwin)
|
||||
# Normalize some abiguous YQ2_ARCH strings
|
||||
YQ2_ARCH ?= $(shell uname -m | sed -e 's/i.86/i386/' -e 's/amd64/x86_64/' -e 's/arm64/aarch64/' -e 's/^arm.*/arm/')
|
||||
else
|
||||
YQ2_ARCH ?= $(shell uname -m)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Refuse all other platforms as a firewall against PEBKAC
|
||||
# (You'll need some #ifdef for your unsupported plattform!)
|
||||
ifeq ($(findstring $(ARCH), i386 x86_64 sparc64),)
|
||||
$(error arch $(ARCH) is currently not supported)
|
||||
# On Windows / MinGW $(CC) is undefined by default.
|
||||
ifeq ($(YQ2_OSTYPE),Windows)
|
||||
CC ?= gcc
|
||||
endif
|
||||
|
||||
# Detect the compiler
|
||||
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang version"), 1)
|
||||
COMPILER := clang
|
||||
COMPILERVER := $(shell $(CC) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/')
|
||||
else ifeq ($(shell $(CC) -v 2>&1 | grep -c -E "(gcc version|gcc-Version)"), 1)
|
||||
COMPILER := gcc
|
||||
COMPILERVER := $(shell $(CC) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/')
|
||||
else
|
||||
COMPILER := unknown
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Base CFLAGS.
|
||||
#
|
||||
# -O2 are enough optimizations.
|
||||
#
|
||||
# -fno-strict-aliasing since the source doesn't comply
|
||||
# with strict aliasing rules and it's next to impossible
|
||||
# to get it there...
|
||||
#
|
||||
# -fomit-frame-pointer since the framepointer is mostly
|
||||
# useless for debugging Quake II and slows things down.
|
||||
#
|
||||
# -g to build allways with debug symbols. Please do not
|
||||
# change this, since it's our only chance to debug this
|
||||
# crap when random crashes happen!
|
||||
#
|
||||
# -fPIC for position independend code.
|
||||
#
|
||||
# -MMD to generate header dependencies.
|
||||
ifeq ($(OSTYPE), Darwin)
|
||||
CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \
|
||||
-Wall -pipe -g -arch i386 -arch x86_64
|
||||
# Base CFLAGS. These may be overridden by the environment.
|
||||
# Highest supported optimizations are -O2, higher levels
|
||||
# will likely break this crappy code.
|
||||
ifdef DEBUG
|
||||
CFLAGS ?= -O0 -g -Wall -pipe
|
||||
else
|
||||
CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \
|
||||
-Wall -pipe -g -MMD
|
||||
CFLAGS ?= -O2 -Wall -pipe -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
# Always needed are:
|
||||
# -fno-strict-aliasing since the source doesn't comply
|
||||
# with strict aliasing rules and it's next to impossible
|
||||
# to get it there...
|
||||
# -fwrapv for defined integer wrapping. MSVC6 did this
|
||||
# and the game code requires it.
|
||||
override CFLAGS += -fno-strict-aliasing -fwrapv
|
||||
|
||||
# -MMD to generate header dependencies. Unsupported by
|
||||
# the Clang shipped with OS X.
|
||||
ifneq ($(YQ2_OSTYPE), Darwin)
|
||||
override CFLAGS += -MMD
|
||||
endif
|
||||
|
||||
# OS X architecture.
|
||||
ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
override CFLAGS += -arch $(YQ2_ARCH)
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Switch off some annoying warnings.
|
||||
ifeq ($(COMPILER), clang)
|
||||
# -Wno-missing-braces because otherwise clang complains
|
||||
# about totally valid 'vec3_t bla = {0}' constructs.
|
||||
CFLAGS += -Wno-missing-braces
|
||||
else ifeq ($(COMPILER), gcc)
|
||||
# GCC 8.0 or higher.
|
||||
ifeq ($(shell test $(COMPILERVER) -ge 80000; echo $$?),0)
|
||||
# -Wno-format-truncation and -Wno-format-overflow
|
||||
# because GCC spams about 50 false positives.
|
||||
CFLAGS += -Wno-format-truncation -Wno-format-overflow
|
||||
endif
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Defines the operating system and architecture
|
||||
override CFLAGS += -DYQ2OSTYPE=\"$(YQ2_OSTYPE)\" -DYQ2ARCH=\"$(YQ2_ARCH)\"
|
||||
|
||||
# ----------
|
||||
|
||||
# For reproducible builds, look here for details:
|
||||
# https://reproducible-builds.org/specs/source-date-epoch/
|
||||
ifdef SOURCE_DATE_EPOCH
|
||||
CFLAGS += -DBUILD_DATE=\"$(shell date --utc --date="@${SOURCE_DATE_EPOCH}" +"%b %_d %Y" | sed -e 's/ /\\ /g')\"
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Using the default x87 float math on 32bit x86 causes rounding trouble
|
||||
# -ffloat-store could work around that, but the better solution is to
|
||||
# just enforce SSE - every x86 CPU since Pentium3 supports that
|
||||
# and this should even improve the performance on old CPUs
|
||||
ifeq ($(YQ2_ARCH), i386)
|
||||
override CFLAGS += -msse -mfpmath=sse
|
||||
endif
|
||||
|
||||
# Force SSE math on x86_64. All sane compilers should do this
|
||||
# anyway, just to protect us from broken Linux distros.
|
||||
ifeq ($(YQ2_ARCH), x86_64)
|
||||
override CFLAGS += -mfpmath=sse
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Base LDFLAGS.
|
||||
ifeq ($(OSTYPE), Darwin)
|
||||
LDFLAGS := -shared -arch i386 -arch x86_64
|
||||
LDFLAGS ?=
|
||||
|
||||
# It's a shared library.
|
||||
override LDFLAGS += -shared
|
||||
|
||||
# Required libraries
|
||||
ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
override LDFLAGS += -arch $(YQ2_ARCH)
|
||||
else ifeq ($(YQ2_OSTYPE), Windows)
|
||||
override LDFLAGS += -static-libgcc
|
||||
else
|
||||
LDFLAGS := -shared
|
||||
override LDFLAGS += -lm
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
@ -80,7 +169,7 @@ endif
|
|||
all: ctf
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# When make is invoked by "make VERBOSE=1" print
|
||||
# the compiler and linker commands.
|
||||
|
||||
|
@ -96,45 +185,39 @@ endif
|
|||
.PHONY : all clean ctf
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# Cleanup
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
clean:
|
||||
@echo "===> CLEAN"
|
||||
@-rmdir /S /Q release build
|
||||
else
|
||||
clean:
|
||||
@echo "===> CLEAN"
|
||||
${Q}rm -Rf build release
|
||||
endif
|
||||
|
||||
|
||||
# ----------
|
||||
|
||||
# The ctf game
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
ctf:
|
||||
@echo "===> Building game.dll"
|
||||
$(Q)tools/mkdir.exe -p release
|
||||
$(Q)mkdir -p release
|
||||
$(MAKE) release/game.dll
|
||||
|
||||
build/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
$(Q)tools/mkdir.exe -p $(@D)
|
||||
$(Q)$(CC) -c $(CFLAGS) -o $@ $<
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
ctf:
|
||||
@echo "===> Building game.dylib"
|
||||
${Q}mkdir -p release
|
||||
$(MAKE) release/game.dylib
|
||||
else
|
||||
ctf:
|
||||
@echo "===> Building game.so"
|
||||
$(Q)mkdir -p release
|
||||
$(MAKE) release/game.so
|
||||
|
||||
release/game.so : CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
build/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
$(Q)mkdir -p $(@D)
|
||||
$(Q)$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
release/game.so : CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
CTF_OBJS_ = \
|
||||
|
@ -163,7 +246,7 @@ CTF_OBJS_ = \
|
|||
src/player/trail.o \
|
||||
src/player/view.o \
|
||||
src/player/weapon.o \
|
||||
src/shared/shared.o
|
||||
src/shared/shared.o
|
||||
|
||||
# ----------
|
||||
|
||||
|
@ -182,14 +265,18 @@ CTF_DEPS= $(CTF_OBJS:.o=.d)
|
|||
|
||||
# ----------
|
||||
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
release/game.dll : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(CTF_OBJS)
|
||||
$(Q)$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
release/game.dylib : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
${Q}$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
else
|
||||
release/game.so : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(CTF_OBJS)
|
||||
$(Q)$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
|
||||
# ----------
|
||||
|
|
32
README
32
README
|
@ -1,32 +0,0 @@
|
|||
This is a 64 bit clean and bugfixed version of id Software's Quake II
|
||||
addon pack "Capture The Flag", developed by David 'Zoid' Kirsch. Hundred
|
||||
of type errors and strange constructs were fixed, thus this version
|
||||
should run much more stable than the old SDK version. While it may work
|
||||
with every Quake II client, the "Yamagi Quake II" client is highly
|
||||
recommended. For more Information visit http://www.yamagi.org/quake2.
|
||||
|
||||
Installation for FreeBSD, Linux and OpenBSD:
|
||||
--------------------------------------------
|
||||
1. Type "make" or "gmake" to compile the game.so.
|
||||
2. Copy release/game.so to the ctf/ subfolder of your Quake II
|
||||
installation. The CTF gamedata is part of the 3.20 point release.
|
||||
3. Start the game with "./quake2 +set game ctf".
|
||||
|
||||
Installation for OS X:
|
||||
----------------------
|
||||
1. Copy game.dll from the zip-archive to ctf/.
|
||||
2. Start the game with "quake2 +set game ctf"
|
||||
|
||||
If you want to compile 'ctf' for OS X from source, please take a look at
|
||||
the "Installation" section of the README of the Yamagi Quake II client.
|
||||
In the same file the integration into an app-bundle is explained.
|
||||
|
||||
Installation for Windows:
|
||||
-------------------------
|
||||
1. Copy the game.dll to the ctf\ subfolder of your Quake II
|
||||
installation. The CTF gamedata is part of the 3.20 point release.
|
||||
2. Start the game with "quake2.exe +set game ctf".
|
||||
|
||||
If you want to compile 'ctf' for Windows from source, please take a
|
||||
look at the "Installation" section of the README of the Yamagi Quake
|
||||
II client. There's descripted how to setup the build environment.
|
66
README.md
Normal file
66
README.md
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Three Wave Capture The Flag for Yamagi Quake II
|
||||
|
||||
Three Wave Capture The Flag for Yamagi Quake II is a bugfixed version of
|
||||
the official CTF addon for Quake II. It's based upon the Quake II source
|
||||
code release and and is licensed under GPL version 2:
|
||||
|
||||
* [LICENSE](https://github.com/yquake2/ctf/blob/master/LICENSE)
|
||||
|
||||
Several bugs were fixed. The addon is intended to be used with Yamagi
|
||||
Quake II, but it's also fully backward compatible with the last Quake II
|
||||
pointrelease 3.20 and may work with other source ports.
|
||||
|
||||
Officially supported operating systems are:
|
||||
|
||||
* FreeBSD
|
||||
* Linux
|
||||
* Windows
|
||||
|
||||
Beside theses Three Wave Capture The Flag for Yamagi Quake II has
|
||||
community support for MacOS and most other unixoid operating systems,
|
||||
including NetBSD, OpenBSD and Solaris.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Three Wave Capture The Flag for Yamagi Quake II is a community driven
|
||||
project and lives from community involvement. Please report bugs in our
|
||||
issue tracker:
|
||||
|
||||
* [Issue Tracker](https://github.com/yquake2/ctf/issues)
|
||||
|
||||
We are always open to code contributions, no matter if they are small
|
||||
bugfixes or bigger features. However, Yamagi Quake II is a conservative
|
||||
project with big focus on stability and backward compatibility. We don't
|
||||
accept breaking changes. When in doubt please open an issue and ask if a
|
||||
contribution in welcome before putting too much work into it. Open a
|
||||
pull request to submit code:
|
||||
|
||||
* [Pull Requests](https://github.com/yquake2/ctf/pulls)
|
||||
|
||||
Also have a look at our contributors guide:
|
||||
|
||||
* [Contributors Guide](https://github.com/yquake2/yquake2/blob/master/doc/080_contributing.md)
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
Yamagi Quake II has rather extensive documentation covering all relevant
|
||||
areas from installation and configuration to package building. Have a
|
||||
look at the documentation index:
|
||||
|
||||
* [Documentation Index](https://github.com/yquake2/yquake2/blob/master/doc/010_index.md)
|
||||
|
||||
|
||||
## Releases
|
||||
|
||||
Three Wave Capture The Flag for Yamagi Quake II releases at an irregular
|
||||
schedule. The official releases with source code tarballs and prebuild
|
||||
Windows binaries can be found at the homepage:
|
||||
|
||||
* [Homepage](https://www.yamagi.org/quake2/)
|
||||
|
||||
Our CI builds **unsupported** Linux, MacOS and Windows binaries at every
|
||||
commit. The artifacts can be found here:
|
||||
|
||||
* [Github Actions](https://github.com/yquake2/ctf/actions)
|
26
src/g_ai.c
26
src/g_ai.c
|
@ -404,7 +404,7 @@ FoundTarget(edict_t *self)
|
|||
level.sight_entity->light_level = 128;
|
||||
}
|
||||
|
||||
self->show_hostile = level.time + 1; /* wake up other monsters */
|
||||
self->show_hostile = (int)level.time + 1; /* wake up other monsters */
|
||||
|
||||
VectorCopy(self->enemy->s.origin, self->monsterinfo.last_sighting);
|
||||
self->monsterinfo.trail_time = level.time;
|
||||
|
@ -577,7 +577,7 @@ FindTarget(edict_t *self)
|
|||
|
||||
if (r == RANGE_NEAR)
|
||||
{
|
||||
if ((client->show_hostile < level.time) && !infront(self, client))
|
||||
if ((client->show_hostile < (int)level.time) && !infront(self, client))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -810,8 +810,11 @@ ai_run_melee(edict_t *self)
|
|||
|
||||
if (FacingIdeal(self))
|
||||
{
|
||||
self->monsterinfo.melee(self);
|
||||
self->monsterinfo.attack_state = AS_STRAIGHT;
|
||||
if (self->monsterinfo.melee)
|
||||
{
|
||||
self->monsterinfo.melee(self);
|
||||
self->monsterinfo.attack_state = AS_STRAIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -827,8 +830,11 @@ ai_run_missile(edict_t *self)
|
|||
|
||||
if (FacingIdeal(self))
|
||||
{
|
||||
self->monsterinfo.attack(self);
|
||||
self->monsterinfo.attack_state = AS_STRAIGHT;
|
||||
if (self->monsterinfo.attack)
|
||||
{
|
||||
self->monsterinfo.attack(self);
|
||||
self->monsterinfo.attack_state = AS_STRAIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,9 +888,9 @@ ai_checkattack(edict_t *self, float dist)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (self->monsterinfo.aiflags & AI_SOUND_TARGET)
|
||||
if ((self->monsterinfo.aiflags & AI_SOUND_TARGET) && !visible(self, self->goalentity))
|
||||
{
|
||||
if ((level.time - self->enemy->teleport_time) > 5.0)
|
||||
if ((level.time - self->enemy->last_sound_time) > 5.0)
|
||||
{
|
||||
if (self->goalentity == self->enemy)
|
||||
{
|
||||
|
@ -908,7 +914,7 @@ ai_checkattack(edict_t *self, float dist)
|
|||
}
|
||||
else
|
||||
{
|
||||
self->show_hostile = level.time + 1;
|
||||
self->show_hostile = (int)level.time + 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -980,7 +986,7 @@ ai_checkattack(edict_t *self, float dist)
|
|||
}
|
||||
}
|
||||
|
||||
self->show_hostile = level.time + 1; /* wake up other monsters */
|
||||
self->show_hostile = (int)level.time + 1; /* wake up other monsters */
|
||||
|
||||
/* check knowledge of enemy */
|
||||
enemy_vis = visible(self, self->enemy);
|
||||
|
|
12
src/g_cmds.c
12
src/g_cmds.c
|
@ -27,11 +27,10 @@
|
|||
#include "header/local.h"
|
||||
#include "monster/player.h"
|
||||
|
||||
char *
|
||||
ClientTeam(edict_t *ent)
|
||||
static char *
|
||||
ClientTeam(edict_t *ent, char* value)
|
||||
{
|
||||
char *p;
|
||||
static char value[512];
|
||||
|
||||
value[0] = 0;
|
||||
|
||||
|
@ -68,10 +67,10 @@ OnSameTeam(edict_t *ent1, edict_t *ent2)
|
|||
return false;
|
||||
}
|
||||
|
||||
strcpy(ent1Team, ClientTeam(ent1));
|
||||
strcpy(ent2Team, ClientTeam(ent2));
|
||||
ClientTeam(ent1, ent1Team);
|
||||
ClientTeam(ent2, ent2Team);
|
||||
|
||||
if (strcmp(ent1Team, ent2Team) == 0)
|
||||
if (ent1Team[0] != '\0' && strcmp(ent1Team, ent2Team) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -230,6 +229,7 @@ Cmd_Give_f(edict_t *ent)
|
|||
if (gi.argc() == 3)
|
||||
{
|
||||
ent->health = atoi(gi.argv(2));
|
||||
ent->health = ent->health < 1 ? 1 : ent->health;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
21
src/g_ctf.c
21
src/g_ctf.c
|
@ -731,7 +731,7 @@ CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker)
|
|||
flag carrier */
|
||||
attacker->client->resp.score += CTF_CARRIER_DANGER_PROTECT_BONUS;
|
||||
gi.bprintf(PRINT_MEDIUM,
|
||||
"%s defends %s's flag carrier against an agressive enemy\n",
|
||||
"%s defends %s's flag carrier against an aggressive enemy\n",
|
||||
attacker->client->pers.netname,
|
||||
CTFTeamName(attacker->client->resp.ctf_team));
|
||||
|
||||
|
@ -1718,8 +1718,7 @@ CTFGrappleDrawCable(edict_t *self)
|
|||
|
||||
AngleVectors(self->owner->client->v_angle, f, r, NULL);
|
||||
VectorSet(offset, 16, 16, self->owner->viewheight - 8);
|
||||
P_ProjectSource(self->owner->client, self->owner->s.origin,
|
||||
offset, f, r, start);
|
||||
P_ProjectSource(self->owner, offset, f, r, start);
|
||||
|
||||
VectorSubtract(start, self->owner->s.origin, offset);
|
||||
|
||||
|
@ -1903,7 +1902,7 @@ CTFGrappleFire(edict_t *ent, vec3_t g_offset, int damage, int effect)
|
|||
AngleVectors(ent->client->v_angle, forward, right, NULL);
|
||||
VectorSet(offset, 24, 8, ent->viewheight - 8 + 2);
|
||||
VectorAdd(offset, g_offset, offset);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
@ -3621,7 +3620,7 @@ CTFWinElection(void)
|
|||
gi.bprintf(PRINT_HIGH, "%s has become an admin.\n",
|
||||
ctfgame.etarget->client->pers.netname);
|
||||
gi.cprintf(ctfgame.etarget, PRINT_HIGH,
|
||||
"Type 'admin' to access the adminstration menu.\n");
|
||||
"Type 'admin' to access the administration menu.\n");
|
||||
break;
|
||||
|
||||
case ELECT_MAP:
|
||||
|
@ -3723,7 +3722,7 @@ CTFReady(edict_t *ent)
|
|||
|
||||
if (ent->client->resp.ready)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "You have already commited.\n");
|
||||
gi.cprintf(ent, PRINT_HIGH, "You have already committed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3758,8 +3757,8 @@ CTFReady(edict_t *ent)
|
|||
|
||||
if (!j && t1 && t2)
|
||||
{
|
||||
/* everyone has commited */
|
||||
gi.bprintf(PRINT_CHAT, "All players have commited. Match starting\n");
|
||||
/* everyone has committed */
|
||||
gi.bprintf(PRINT_CHAT, "All players have committed. Match starting\n");
|
||||
ctfgame.match = MATCH_PREGAME;
|
||||
ctfgame.matchtime = level.time + matchstarttime->value;
|
||||
ctfgame.countdown = false;
|
||||
|
@ -3785,7 +3784,7 @@ CTFNotReady(edict_t *ent)
|
|||
|
||||
if (!ent->client->resp.ready)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "You haven't commited.\n");
|
||||
gi.cprintf(ent, PRINT_HIGH, "You haven't committed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5013,7 +5012,7 @@ CTFAdmin_Reset(edict_t *ent, pmenuhnd_t *p)
|
|||
PMenu_Close(ent);
|
||||
|
||||
/* go back to normal mode */
|
||||
gi.bprintf(PRINT_CHAT, "Match mode has been terminated, reseting to normal game.\n");
|
||||
gi.bprintf(PRINT_CHAT, "Match mode has been terminated, resetting to normal game.\n");
|
||||
ctfgame.match = MATCH_NONE;
|
||||
gi.cvar_set("competition", "1");
|
||||
CTFResetAllPlayers();
|
||||
|
@ -5082,7 +5081,7 @@ CTFAdmin(edict_t *ent)
|
|||
ent->client->resp.admin = true;
|
||||
gi.bprintf(PRINT_HIGH, "%s has become an admin.\n",
|
||||
ent->client->pers.netname);
|
||||
gi.cprintf(ent, PRINT_HIGH, "Type 'admin' to access the adminstration menu.\n");
|
||||
gi.cprintf(ent, PRINT_HIGH, "Type 'admin' to access the administration menu.\n");
|
||||
}
|
||||
|
||||
if (!ent->client->resp.admin)
|
||||
|
|
10
src/g_main.c
10
src/g_main.c
|
@ -77,6 +77,8 @@ cvar_t *flood_waitdelay;
|
|||
|
||||
cvar_t *sv_maplist;
|
||||
|
||||
cvar_t *aimfix;
|
||||
|
||||
void SpawnEntities(char *mapname, char *entities, char *spawnpoint);
|
||||
void ClientThink(edict_t *ent, usercmd_t *cmd);
|
||||
qboolean ClientConnect(edict_t *ent, char *userinfo);
|
||||
|
@ -279,7 +281,7 @@ EndDMLevel(void)
|
|||
ent = G_Find(NULL, FOFS(classname), "target_changelevel");
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
{
|
||||
/* the map designer didn't include a changelevel,
|
||||
so create a fake ent that goes back to the same level */
|
||||
BeginIntermission(CreateTargetChangeLevel(level.mapname));
|
||||
|
@ -384,6 +386,9 @@ ExitLevel(void)
|
|||
ent->health = ent->client->pers.max_health;
|
||||
}
|
||||
}
|
||||
|
||||
gibsthisframe = 0;
|
||||
debristhisframe = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,6 +403,9 @@ G_RunFrame(void)
|
|||
level.framenum++;
|
||||
level.time = level.framenum * FRAMETIME;
|
||||
|
||||
gibsthisframe = 0;
|
||||
debristhisframe = 0;
|
||||
|
||||
/* choose a client for monsters to target this frame */
|
||||
AI_SetSightClient();
|
||||
|
||||
|
|
48
src/g_misc.c
48
src/g_misc.c
|
@ -1,7 +1,7 @@
|
|||
#include "header/local.h"
|
||||
|
||||
int gibsthisframe = 0;
|
||||
int lastgibframe = 0;
|
||||
int debristhisframe;
|
||||
int gibsthisframe;
|
||||
|
||||
/*
|
||||
* QUAKED func_group (0 0 0) ?
|
||||
|
@ -139,15 +139,9 @@ ThrowGib(edict_t *self, char *gibname, int damage, int type)
|
|||
vec3_t size;
|
||||
float vscale;
|
||||
|
||||
if (level.framenum > lastgibframe)
|
||||
{
|
||||
gibsthisframe = 0;
|
||||
lastgibframe = level.framenum;
|
||||
}
|
||||
|
||||
gibsthisframe++;
|
||||
|
||||
if (gibsthisframe > 20)
|
||||
if (gibsthisframe > MAX_GIBS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -161,11 +155,12 @@ ThrowGib(edict_t *self, char *gibname, int damage, int type)
|
|||
gib->s.origin[2] = origin[2] + crandom() * size[2];
|
||||
|
||||
gi.setmodel(gib, gibname);
|
||||
gib->solid = SOLID_NOT;
|
||||
gib->solid = SOLID_BBOX;
|
||||
gib->s.effects |= EF_GIB;
|
||||
gib->flags |= FL_NO_KNOCKBACK;
|
||||
gib->takedamage = DAMAGE_YES;
|
||||
gib->die = gib_die;
|
||||
gib->health = 250;
|
||||
|
||||
if (type == GIB_ORGANIC)
|
||||
{
|
||||
|
@ -205,7 +200,7 @@ ThrowHead(edict_t *self, char *gibname, int damage, int type)
|
|||
|
||||
self->s.modelindex2 = 0;
|
||||
gi.setmodel(self, gibname);
|
||||
self->solid = SOLID_NOT;
|
||||
self->solid = SOLID_BBOX;
|
||||
self->s.effects |= EF_GIB;
|
||||
self->s.effects &= ~EF_FLIES;
|
||||
self->s.sound = 0;
|
||||
|
@ -262,7 +257,7 @@ ThrowClientHead(edict_t *self, int damage)
|
|||
VectorSet(self->maxs, 16, 16, 16);
|
||||
|
||||
self->takedamage = DAMAGE_NO;
|
||||
self->solid = SOLID_NOT;
|
||||
self->solid = SOLID_BBOX;
|
||||
self->s.effects = EF_GIB;
|
||||
self->s.sound = 0;
|
||||
self->flags |= FL_NO_KNOCKBACK;
|
||||
|
@ -293,15 +288,9 @@ ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin)
|
|||
edict_t *chunk;
|
||||
vec3_t v;
|
||||
|
||||
if (level.framenum > lastgibframe)
|
||||
{
|
||||
gibsthisframe = 0;
|
||||
lastgibframe = level.framenum;
|
||||
}
|
||||
debristhisframe++;
|
||||
|
||||
gibsthisframe++;
|
||||
|
||||
if (gibsthisframe > 20)
|
||||
if (debristhisframe > MAX_DEBRIS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -314,7 +303,7 @@ ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin)
|
|||
v[2] = 100 + 100 * crandom();
|
||||
VectorMA(self->velocity, speed, v, chunk->velocity);
|
||||
chunk->movetype = MOVETYPE_BOUNCE;
|
||||
chunk->solid = SOLID_NOT;
|
||||
chunk->solid = SOLID_BBOX;
|
||||
chunk->avelocity[0] = random() * 600;
|
||||
chunk->avelocity[1] = random() * 600;
|
||||
chunk->avelocity[2] = random() * 600;
|
||||
|
@ -325,6 +314,7 @@ ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin)
|
|||
chunk->classname = "debris";
|
||||
chunk->takedamage = DAMAGE_YES;
|
||||
chunk->die = debris_die;
|
||||
chunk->health = 250;
|
||||
gi.linkentity(chunk);
|
||||
}
|
||||
|
||||
|
@ -344,7 +334,7 @@ BecomeExplosion1(edict_t *self)
|
|||
{
|
||||
CTFResetFlag(CTF_TEAM2); /* this will free self! */
|
||||
gi.bprintf(PRINT_HIGH, "The %s flag has returned!\n",
|
||||
CTFTeamName(CTF_TEAM1));
|
||||
CTFTeamName(CTF_TEAM2));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -972,7 +962,7 @@ void
|
|||
SP_func_explosive(edict_t *self)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
{
|
||||
/* auto-remove for deathmatch */
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
|
@ -1147,7 +1137,7 @@ void
|
|||
SP_misc_explobox(edict_t *self)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
{
|
||||
/* auto-remove for deathmatch */
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
|
@ -1438,7 +1428,7 @@ void
|
|||
SP_misc_deadsoldier(edict_t *ent)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
{
|
||||
/* auto-remove for deathmatch */
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
|
@ -1744,7 +1734,7 @@ void
|
|||
SP_misc_gib_arm(edict_t *ent)
|
||||
{
|
||||
gi.setmodel(ent, "models/objects/gibs/arm/tris.md2");
|
||||
ent->solid = SOLID_NOT;
|
||||
ent->solid = SOLID_BBOX;
|
||||
ent->s.effects |= EF_GIB;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = gib_die;
|
||||
|
@ -1767,7 +1757,7 @@ void
|
|||
SP_misc_gib_leg(edict_t *ent)
|
||||
{
|
||||
gi.setmodel(ent, "models/objects/gibs/leg/tris.md2");
|
||||
ent->solid = SOLID_NOT;
|
||||
ent->solid = SOLID_BBOX;
|
||||
ent->s.effects |= EF_GIB;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = gib_die;
|
||||
|
@ -1790,7 +1780,7 @@ void
|
|||
SP_misc_gib_head(edict_t *ent)
|
||||
{
|
||||
gi.setmodel(ent, "models/objects/gibs/head/tris.md2");
|
||||
ent->solid = SOLID_NOT;
|
||||
ent->solid = SOLID_BBOX;
|
||||
ent->s.effects |= EF_GIB;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = gib_die;
|
||||
|
@ -2136,7 +2126,7 @@ teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
|||
/* set angles */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
other->client->ps.pmove.delta_angles[i] =
|
||||
other->client->ps.pmove.delta_angles[i] =
|
||||
ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]);
|
||||
}
|
||||
|
||||
|
|
58
src/g_phys.c
58
src/g_phys.c
|
@ -144,7 +144,7 @@ SV_Impact(edict_t *e1, trace_t *trace)
|
|||
|
||||
/*
|
||||
* Slide off of the impacting object
|
||||
* returns the blocked flags (1 = floor,
|
||||
* returns the blocked flags (1 = floor,
|
||||
* 2 = step / wall)
|
||||
*/
|
||||
#define STOP_EPSILON 0.1
|
||||
|
@ -229,14 +229,14 @@ SV_FlyMove(edict_t *ent, float time, int mask)
|
|||
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, mask);
|
||||
|
||||
if (trace.allsolid)
|
||||
{
|
||||
{
|
||||
/* entity is trapped in another solid */
|
||||
VectorCopy(vec3_origin, ent->velocity);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (trace.fraction > 0)
|
||||
{
|
||||
{
|
||||
/* actually covered some distance */
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
VectorCopy(ent->velocity, original_velocity);
|
||||
|
@ -278,7 +278,7 @@ SV_FlyMove(edict_t *ent, float time, int mask)
|
|||
|
||||
/* cliped to another plane */
|
||||
if (numplanes >= MAX_CLIP_PLANES)
|
||||
{
|
||||
{
|
||||
/* this shouldn't really happen */
|
||||
VectorCopy(vec3_origin, ent->velocity);
|
||||
return 3;
|
||||
|
@ -310,13 +310,13 @@ SV_FlyMove(edict_t *ent, float time, int mask)
|
|||
}
|
||||
|
||||
if (i != numplanes)
|
||||
{
|
||||
{
|
||||
/* go along this plane */
|
||||
VectorCopy(new_velocity, ent->velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
/* go along the crease */
|
||||
if (numplanes != 2)
|
||||
{
|
||||
|
@ -329,7 +329,7 @@ SV_FlyMove(edict_t *ent, float time, int mask)
|
|||
VectorScale(dir, d, ent->velocity);
|
||||
}
|
||||
|
||||
/* if original velocity is against the original velocity,
|
||||
/* if original velocity is against the original velocity,
|
||||
stop dead to avoid tiny occilations in sloping corners */
|
||||
if (DotProduct(ent->velocity, primal_velocity) <= 0)
|
||||
{
|
||||
|
@ -497,6 +497,22 @@ retry:
|
|||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
gi.linkentity(ent);
|
||||
|
||||
/* Push slightly away from non-horizontal surfaces,
|
||||
prevent origin stuck in the plane which causes
|
||||
the entity to be rendered in full black. */
|
||||
if (trace.plane.type != 2)
|
||||
{
|
||||
/* Limit the fix to gibs, debris and dead monsters.
|
||||
Everything else may break existing maps. Items
|
||||
may slide to unreachable locations, monsters may
|
||||
get stuck, etc. */
|
||||
if (((strncmp(ent->classname, "monster_", 8) == 0) && ent->health < 1) ||
|
||||
(strcmp(ent->classname, "debris") == 0) || (ent->s.effects & EF_GIB))
|
||||
{
|
||||
VectorAdd(ent->s.origin, trace.plane.normal, ent->s.origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (trace.fraction != 1.0)
|
||||
{
|
||||
SV_Impact(ent, &trace);
|
||||
|
@ -543,7 +559,7 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
vec3_t org, org2, move2, forward, right, up;
|
||||
vec3_t realmins, realmaxs;
|
||||
|
||||
/* clamp the move to 1/8 units, so the position will
|
||||
/* clamp the move to 1/8 units, so the position will
|
||||
be accurate for client side prediction */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
|
@ -644,7 +660,7 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
VectorAdd(check->s.origin, move, check->s.origin);
|
||||
|
||||
if (check->client)
|
||||
{
|
||||
{
|
||||
check->client->ps.pmove.delta_angles[YAW] += amove[YAW];
|
||||
}
|
||||
|
||||
|
@ -665,13 +681,13 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
block = SV_TestEntityPosition(check);
|
||||
|
||||
if (!block)
|
||||
{
|
||||
{
|
||||
/* pushed ok */
|
||||
gi.linkentity(check);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if it is ok to leave in the old position, do it
|
||||
/* if it is ok to leave in the old position, do it
|
||||
this is only relevent for riding entities, not pushed */
|
||||
VectorSubtract(check->s.origin, move, check->s.origin);
|
||||
block = SV_TestEntityPosition(check);
|
||||
|
@ -686,7 +702,7 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
/* save off the obstacle so we can call the block function */
|
||||
obstacle = check;
|
||||
|
||||
/* move back any entities we already moved
|
||||
/* move back any entities we already moved
|
||||
go backwards, so if the same entity was pushed/
|
||||
twice, it goes back to the original position */
|
||||
for (p = pushed_p - 1; p >= pushed; p--)
|
||||
|
@ -715,7 +731,7 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
}
|
||||
|
||||
/*
|
||||
* Bmodel objects don't interact with each
|
||||
* Bmodel objects don't interact with each
|
||||
* other, but push all box objects
|
||||
*/
|
||||
void
|
||||
|
@ -730,8 +746,8 @@ SV_Physics_Pusher(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
/* make sure all team slaves can move before commiting any moves
|
||||
or calling any think functions if the move is blocked, all
|
||||
/* make sure all team slaves can move before commiting any moves
|
||||
or calling any think functions if the move is blocked, all
|
||||
moved objects will be backed out */
|
||||
pushed_p = pushed;
|
||||
|
||||
|
@ -739,7 +755,7 @@ SV_Physics_Pusher(edict_t *ent)
|
|||
{
|
||||
if (part->velocity[0] || part->velocity[1] || part->velocity[2] ||
|
||||
part->avelocity[0] || part->avelocity[1] || part->avelocity[2])
|
||||
{
|
||||
{
|
||||
/* object is moving */
|
||||
VectorScale(part->velocity, FRAMETIME, move);
|
||||
VectorScale(part->avelocity, FRAMETIME, amove);
|
||||
|
@ -751,9 +767,9 @@ SV_Physics_Pusher(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
if (pushed_p > &pushed[MAX_EDICTS])
|
||||
if (pushed_p > &pushed[MAX_EDICTS-1])
|
||||
{
|
||||
gi.error(ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted");
|
||||
gi.error("pushed_p > &pushed[MAX_EDICTS-1], memory corrupted");
|
||||
}
|
||||
|
||||
if (part)
|
||||
|
@ -767,8 +783,8 @@ SV_Physics_Pusher(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/* if the pusher has a "blocked" function, call it
|
||||
otherwise, just stay in place until the obstacle
|
||||
/* if the pusher has a "blocked" function, call it
|
||||
otherwise, just stay in place until the obstacle
|
||||
is gone */
|
||||
if (part->blocked)
|
||||
{
|
||||
|
@ -1036,7 +1052,7 @@ SV_Physics_Step(edict_t *ent)
|
|||
}
|
||||
|
||||
/* add gravity except:
|
||||
flying monsters
|
||||
flying monsters
|
||||
swimming monsters who are in the water */
|
||||
if (!wasonground)
|
||||
{
|
||||
|
|
15
src/g_save.c
15
src/g_save.c
|
@ -28,6 +28,10 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
#ifndef BUILD_DATE
|
||||
#define BUILD_DATE __DATE__
|
||||
#endif
|
||||
|
||||
field_t fields[] = {
|
||||
{"classname", FOFS(classname), F_LSTRING},
|
||||
{"origin", FOFS(s.origin), F_VECTOR},
|
||||
|
@ -141,7 +145,7 @@ void
|
|||
InitGame(void)
|
||||
{
|
||||
gi.dprintf("Game is starting up.\n");
|
||||
gi.dprintf("Game is ctf.\n");
|
||||
gi.dprintf("Game is ctf built on %s.\n", GAMEVERSION, BUILD_DATE);
|
||||
|
||||
gun_x = gi.cvar("gun_x", "0", 0);
|
||||
gun_y = gi.cvar("gun_y", "0", 0);
|
||||
|
@ -157,7 +161,7 @@ InitGame(void)
|
|||
/* latched vars */
|
||||
sv_cheats = gi.cvar("cheats", "0", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
gi.cvar("gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_LATCH);
|
||||
gi.cvar("gamedate", __DATE__, CVAR_SERVERINFO | CVAR_LATCH);
|
||||
gi.cvar("gamedate", BUILD_DATE, CVAR_SERVERINFO | CVAR_LATCH);
|
||||
maxclients = gi.cvar("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
deathmatch = gi.cvar("deathmatch", "0", CVAR_LATCH);
|
||||
coop = gi.cvar("coop", "0", CVAR_LATCH);
|
||||
|
@ -200,6 +204,9 @@ InitGame(void)
|
|||
/* dm map list */
|
||||
sv_maplist = gi.cvar("sv_maplist", "", 0);
|
||||
|
||||
/* others */
|
||||
aimfix = gi.cvar("aimfix", "0", CVAR_ARCHIVE);
|
||||
|
||||
/* items */
|
||||
InitItems();
|
||||
|
||||
|
@ -493,7 +500,7 @@ WriteGame(char *filename, qboolean autosave)
|
|||
}
|
||||
|
||||
memset(str, 0, sizeof(str));
|
||||
strcpy(str, __DATE__);
|
||||
strcpy(str, BUILD_DATE);
|
||||
fwrite(str, sizeof(str), 1, f);
|
||||
|
||||
game.autosaved = autosave;
|
||||
|
@ -526,7 +533,7 @@ ReadGame(char *filename)
|
|||
|
||||
fread(str, sizeof(str), 1, f);
|
||||
|
||||
if (strcmp(str, __DATE__))
|
||||
if (strcmp(str, BUILD_DATE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an older version.\n");
|
||||
|
|
|
@ -813,11 +813,11 @@ SP_worldspawn(edict_t *ent)
|
|||
if (ent->message && ent->message[0])
|
||||
{
|
||||
gi.configstring(CS_NAME, ent->message);
|
||||
strncpy(level.level_name, ent->message, sizeof(level.level_name));
|
||||
Q_strlcpy(level.level_name, ent->message, sizeof(level.level_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(level.level_name, level.mapname, sizeof(level.level_name));
|
||||
Q_strlcpy(level.level_name, level.mapname, sizeof(level.level_name));
|
||||
}
|
||||
|
||||
if (st.sky && st.sky[0])
|
||||
|
|
|
@ -168,11 +168,11 @@ SV_FilterPacket(char *from)
|
|||
{
|
||||
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||
{
|
||||
return (int)filterban->value;
|
||||
return (filterban->value != 0);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)!filterban->value;
|
||||
return (filterban->value == 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -121,7 +121,7 @@ SP_target_speaker(edict_t *ent)
|
|||
}
|
||||
else
|
||||
{
|
||||
strncpy(buffer, st.noise, sizeof(buffer));
|
||||
Q_strlcpy(buffer, st.noise, sizeof(buffer));
|
||||
}
|
||||
|
||||
ent->noise_index = gi.soundindex(buffer);
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
/*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*
|
||||
*
|
||||
* THIS FILE IS _VERY_ FRAGILE AND THERE'S NOTHING IN IT THAT CAN OR
|
||||
* MUST BE CHANGED. IT'S MOST LIKELY A VERY GOOD IDEA TO CLOSE THE
|
||||
* EDITOR NOW AND NEVER LOOK BACK. OTHERWISE YOU MAY SCREW UP EVERYTHING!
|
||||
* EDITOR NOW AND NEVER LOOK BACK. OTHERWISE YOU MAY SCREW UP EVERYTHING!
|
||||
*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
@ -209,7 +209,5 @@ typedef struct
|
|||
int max_edicts;
|
||||
} game_export_t;
|
||||
|
||||
game_export_t *GetGameApi(game_import_t *import);
|
||||
|
||||
#endif /* CTF_GAME_H */
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
/* define GAME_INCLUDE so that game.h does not define the
|
||||
/* define GAME_INCLUDE so that game.h does not define the
|
||||
short, server-visible gclient_t and edict_t structures,
|
||||
because we define the full size ones in this file */
|
||||
#define GAME_INCLUDE
|
||||
|
@ -110,6 +110,10 @@ typedef enum
|
|||
AMMO_SLUGS
|
||||
} ammo_t;
|
||||
|
||||
/* Maximum debris / gibs per frame */
|
||||
#define MAX_GIBS 20
|
||||
#define MAX_DEBRIS 20
|
||||
|
||||
/* deadflag */
|
||||
#define DEAD_NO 0
|
||||
#define DEAD_DYING 1
|
||||
|
@ -259,8 +263,8 @@ typedef struct gitem_s
|
|||
char *precaches; /* string of all models, sounds, and images this item will use */
|
||||
} gitem_t;
|
||||
|
||||
/* this structure is left intact through an entire game
|
||||
it should be initialized at dll load time, and read/written to
|
||||
/* this structure is left intact through an entire game
|
||||
it should be initialized at dll load time, and read/written to
|
||||
the server.ssv file for savegames */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -271,7 +275,7 @@ typedef struct
|
|||
|
||||
gclient_t *clients; /* [maxclients] */
|
||||
|
||||
/* can't store spawnpoint in level, because
|
||||
/* can't store spawnpoint in level, because
|
||||
it would get overwritten by the savegame restore */
|
||||
char spawnpoint[512]; /* needed for coop respawns */
|
||||
|
||||
|
@ -288,7 +292,7 @@ typedef struct
|
|||
qboolean autosaved;
|
||||
} game_locals_t;
|
||||
|
||||
/* this structure is cleared as each map is entered
|
||||
/* this structure is cleared as each map is entered
|
||||
it is read/written to the level.sav file for savegames */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -333,8 +337,8 @@ typedef struct
|
|||
int power_cubes; /* ugly necessity for coop */
|
||||
} level_locals_t;
|
||||
|
||||
/* spawn_temp_t is only used to hold entity field values that
|
||||
can be set from the editor, but aren't actualy present
|
||||
/* spawn_temp_t is only used to hold entity field values that
|
||||
can be set from the editor, but aren't actualy present
|
||||
in edict_t during gameplay */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -446,6 +450,10 @@ extern spawn_temp_t st;
|
|||
extern int sm_meat_index;
|
||||
extern int snd_fry;
|
||||
|
||||
extern int debristhisframe;
|
||||
extern int gibsthisframe;
|
||||
|
||||
|
||||
/* means of death */
|
||||
#define MOD_UNKNOWN 0
|
||||
#define MOD_BLASTER 1
|
||||
|
@ -533,6 +541,8 @@ extern cvar_t *flood_waitdelay;
|
|||
|
||||
extern cvar_t *sv_maplist;
|
||||
|
||||
extern cvar_t *aimfix;
|
||||
|
||||
#define world (&g_edicts[0])
|
||||
|
||||
/* item spawnflags */
|
||||
|
@ -543,7 +553,7 @@ extern cvar_t *sv_maplist;
|
|||
#define DROPPED_PLAYER_ITEM 0x00020000
|
||||
#define ITEM_TARGETS_USED 0x00040000
|
||||
|
||||
/* fields are needed for spawning from the entity string
|
||||
/* fields are needed for spawning from the entity string
|
||||
and saving / loading games */
|
||||
#define FFL_SPAWNTEMP 1
|
||||
|
||||
|
@ -752,7 +762,7 @@ void DeathmatchScoreboardMessage(edict_t *client, edict_t *killer);
|
|||
|
||||
/* g_pweapon.c */
|
||||
void PlayerNoise(edict_t *who, vec3_t where, int type);
|
||||
void P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance,
|
||||
void P_ProjectSource(edict_t *ent, vec3_t distance,
|
||||
vec3_t forward, vec3_t right, vec3_t result);
|
||||
void Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
||||
int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames,
|
||||
|
@ -793,7 +803,7 @@ typedef struct
|
|||
char netname[16];
|
||||
int hand;
|
||||
|
||||
qboolean connected; /* a loadgame will leave valid entities that
|
||||
qboolean connected; /* a loadgame will leave valid entities that
|
||||
just don't have a connection yet */
|
||||
|
||||
/* values saved and restored from edicts when changing levels */
|
||||
|
@ -842,7 +852,7 @@ typedef struct
|
|||
int helpchanged;
|
||||
} client_respawn_t;
|
||||
|
||||
/* this structure is cleared on each PutClientInServer(),
|
||||
/* this structure is cleared on each PutClientInServer(),
|
||||
except for 'client->pers' */
|
||||
struct gclient_s
|
||||
{
|
||||
|
@ -872,7 +882,7 @@ struct gclient_s
|
|||
|
||||
gitem_t *newweapon;
|
||||
|
||||
/* sum up damage over an entire frame, so
|
||||
/* sum up damage over an entire frame, so
|
||||
shotgun blasts give a single big kick */
|
||||
int damage_armor; /* damage absorbed by armor */
|
||||
int damage_parmor; /* damage absorbed by power armor */
|
||||
|
@ -941,9 +951,9 @@ struct gclient_s
|
|||
struct edict_s
|
||||
{
|
||||
entity_state_t s;
|
||||
struct gclient_s *client; /* NULL if not a player
|
||||
the server expects the first part
|
||||
of gclient_s to be a player_state_t
|
||||
struct gclient_s *client; /* NULL if not a player
|
||||
the server expects the first part
|
||||
of gclient_s to be a player_state_t
|
||||
but the rest of it is opaque */
|
||||
|
||||
qboolean inuse;
|
||||
|
@ -1000,7 +1010,7 @@ struct edict_s
|
|||
vec3_t avelocity;
|
||||
int mass;
|
||||
float air_finished;
|
||||
float gravity; /* per entity gravity multiplier (1.0 is normal)
|
||||
float gravity; /* per entity gravity multiplier (1.0 is normal)
|
||||
use for lowgrav artifact, flares */
|
||||
|
||||
edict_t *goalentity;
|
||||
|
@ -1029,7 +1039,7 @@ struct edict_s
|
|||
int max_health;
|
||||
int gib_health;
|
||||
int deadflag;
|
||||
qboolean show_hostile;
|
||||
int show_hostile;
|
||||
|
||||
float powerarmor_time;
|
||||
|
||||
|
@ -1065,7 +1075,7 @@ struct edict_s
|
|||
float delay; /* before firing targets */
|
||||
float random;
|
||||
|
||||
float teleport_time;
|
||||
float last_sound_time;
|
||||
|
||||
int watertype;
|
||||
int waterlevel;
|
||||
|
|
|
@ -36,8 +36,21 @@
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L // C23 or newer
|
||||
typedef bool qboolean;
|
||||
#else
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
|
||||
typedef enum {false, true} qboolean;
|
||||
#endif
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
|
@ -202,6 +215,8 @@ void Com_PageInMemory(byte *buffer, int size);
|
|||
int Q_stricmp(const char *s1, const char *s2);
|
||||
int Q_strcasecmp(char *s1, char *s2);
|
||||
int Q_strncasecmp(char *s1, char *s2, int n);
|
||||
int Q_strlcpy(char *dst, const char *src, int size);
|
||||
int Q_strlcat(char *dst, const char *src, int size);
|
||||
|
||||
/* ============================================= */
|
||||
|
||||
|
|
|
@ -527,7 +527,7 @@ SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist)
|
|||
}
|
||||
|
||||
/* try other directions */
|
||||
if (((rand() & 3) & 1) || (abs(deltay) > abs(deltax)))
|
||||
if (((rand() & 3) & 1) || (fabsf(deltay) > fabsf(deltax)))
|
||||
{
|
||||
tdir = d[1];
|
||||
d[1] = d[2];
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Interface between client <-> game and client calculations.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "../header/local.h"
|
||||
#include "../monster/player.h"
|
||||
|
@ -76,11 +76,11 @@ SP_info_player_coop(edict_t *self)
|
|||
/*
|
||||
* QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32)
|
||||
* The deathmatch intermission point will be at one of these
|
||||
* Use 'angles' instead of 'angle', so you can set pitch or
|
||||
* Use 'angles' instead of 'angle', so you can set pitch or
|
||||
* roll as well as yaw. 'pitch yaw roll'
|
||||
*/
|
||||
void
|
||||
SP_info_player_intermission(void)
|
||||
SP_info_player_intermission(edict_t *ent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ SP_info_player_intermission(void)
|
|||
void
|
||||
player_pain(edict_t *self, edict_t *other, float kick, int damage)
|
||||
{
|
||||
/* player pain is handled at the
|
||||
/* player pain is handled at the
|
||||
end of the frame in P_DamageFeedback */
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
memset(self->client->pers.inventory, 0, sizeof(self->client->pers.inventory));
|
||||
|
||||
if (self->health < -40)
|
||||
{
|
||||
{
|
||||
/* gib */
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex(
|
||||
"misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
@ -586,7 +586,7 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
/* ======================================================================= */
|
||||
|
||||
/*
|
||||
* This is only called when the game
|
||||
* This is only called when the game
|
||||
* first initializes in single player,
|
||||
* but is called after each death and
|
||||
* level change in deathmatch
|
||||
|
@ -731,7 +731,7 @@ PlayersRangeFromSpot(edict_t *spot)
|
|||
}
|
||||
|
||||
/*
|
||||
* go to a random point, but NOT the two
|
||||
* go to a random point, but NOT the two
|
||||
* points closest to other players
|
||||
*/
|
||||
edict_t *
|
||||
|
@ -824,7 +824,7 @@ SelectFarthestDeathmatchSpawnPoint(void)
|
|||
return bestspot;
|
||||
}
|
||||
|
||||
/* if there is a player just spawned on
|
||||
/* if there is a player just spawned on
|
||||
each and every start spot we have no
|
||||
choice to turn one into a telefrag meltdown */
|
||||
spot = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
|
||||
|
@ -880,7 +880,7 @@ SelectCoopSpawnPoint(edict_t *ent)
|
|||
}
|
||||
|
||||
if (Q_stricmp(game.spawnpoint, target) == 0)
|
||||
{
|
||||
{
|
||||
/* this is a coop spawn point for one of the clients here */
|
||||
index--;
|
||||
|
||||
|
@ -942,7 +942,7 @@ SelectSpawnPoint(edict_t *ent, vec3_t origin, vec3_t angles)
|
|||
if (!spot)
|
||||
{
|
||||
if (!game.spawnpoint[0])
|
||||
{
|
||||
{
|
||||
/* there wasn't a spawnpoint without a target, so use any */
|
||||
spot = G_Find(spot, FOFS(classname), "info_player_start");
|
||||
}
|
||||
|
@ -1062,7 +1062,7 @@ respawn(edict_t *self)
|
|||
/* ============================================================== */
|
||||
|
||||
/*
|
||||
* Called when a player connects
|
||||
* Called when a player connects
|
||||
* to a server or respawns in
|
||||
* a deathmatch.
|
||||
*/
|
||||
|
@ -1225,7 +1225,7 @@ PutClientInServer(edict_t *ent)
|
|||
}
|
||||
|
||||
if (!KillBox(ent))
|
||||
{
|
||||
{
|
||||
/* could't spawn in? */
|
||||
}
|
||||
|
||||
|
@ -1237,7 +1237,7 @@ PutClientInServer(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* A client has just connected to
|
||||
* A client has just connected to
|
||||
* the server in deathmatch mode,
|
||||
* so clear everything out before
|
||||
* starting them.
|
||||
|
@ -1288,13 +1288,13 @@ ClientBegin(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
/* if there is already a body waiting for
|
||||
/* if there is already a body waiting for
|
||||
us (a loadgame), just take it, otherwise
|
||||
spawn one from scratch */
|
||||
if (ent->inuse == true)
|
||||
{
|
||||
/* the client has cleared the client side viewangles upon
|
||||
connecting to the server, which is different than the
|
||||
/* the client has cleared the client side viewangles upon
|
||||
connecting to the server, which is different than the
|
||||
state when the game is saved, so we need to compensate
|
||||
with deltaangles */
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -1305,7 +1305,7 @@ ClientBegin(edict_t *ent)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* a spawn point will completely reinitialize the entity
|
||||
/* a spawn point will completely reinitialize the entity
|
||||
except for the persistant data that was initialized at
|
||||
ClientConnect() time */
|
||||
G_InitEdict(ent);
|
||||
|
@ -1513,9 +1513,9 @@ ClientDisconnect(edict_t *ent)
|
|||
|
||||
edict_t *pm_passent;
|
||||
|
||||
/*
|
||||
/*
|
||||
* pmove doesn't need to know about
|
||||
* passent and contentmask
|
||||
* passent and contentmask
|
||||
*/
|
||||
trace_t
|
||||
PM_trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
|
||||
|
@ -1620,7 +1620,10 @@ ClientThink(edict_t *ent, usercmd_t *ucmd)
|
|||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
pm.s.origin[i] = ent->s.origin[i] * 8;
|
||||
pm.s.velocity[i] = ent->velocity[i] * 8;
|
||||
/* save to an int first, in case the short overflows
|
||||
* so we get defined behavior (at least with -fwrapv) */
|
||||
int tmpVel = ent->velocity[i] * 8;
|
||||
pm.s.velocity[i] = tmpVel;
|
||||
}
|
||||
|
||||
if (memcmp(&client->old_pmove, &pm.s, sizeof(pm.s)))
|
||||
|
@ -1724,7 +1727,7 @@ ClientThink(edict_t *ent, usercmd_t *ucmd)
|
|||
client->buttons = ucmd->buttons;
|
||||
client->latched_buttons |= client->buttons & ~client->oldbuttons;
|
||||
|
||||
/* save light level the player is
|
||||
/* save light level the player is
|
||||
standing on for monster sighting AI */
|
||||
ent->light_level = ucmd->lightlevel;
|
||||
|
||||
|
|
|
@ -33,10 +33,12 @@ static byte is_silenced;
|
|||
void weapon_grenade_fire(edict_t *ent, qboolean held);
|
||||
|
||||
void
|
||||
P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance,
|
||||
P_ProjectSource(edict_t *ent, vec3_t distance,
|
||||
vec3_t forward, vec3_t right, vec3_t result)
|
||||
{
|
||||
vec3_t _distance;
|
||||
gclient_t *client = ent->client;
|
||||
float *point = ent->s.origin;
|
||||
vec3_t _distance;
|
||||
|
||||
VectorCopy(distance, _distance);
|
||||
|
||||
|
@ -50,6 +52,21 @@ P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance,
|
|||
}
|
||||
|
||||
G_ProjectSource(point, _distance, forward, right, result);
|
||||
|
||||
// Berserker: fix - now the projectile hits exactly where the scope is pointing.
|
||||
if (aimfix->value)
|
||||
{
|
||||
vec3_t start, end;
|
||||
VectorSet(start, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] + ent->viewheight);
|
||||
VectorMA(start, 8192, forward, end);
|
||||
|
||||
trace_t tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT);
|
||||
if (tr.fraction < 1)
|
||||
{
|
||||
VectorSubtract(tr.endpos, result, forward);
|
||||
VectorNormalize(forward);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,7 +136,7 @@ PlayerNoise(edict_t *who, vec3_t where, int type)
|
|||
VectorCopy(where, noise->s.origin);
|
||||
VectorSubtract(where, noise->maxs, noise->absmin);
|
||||
VectorAdd(where, noise->maxs, noise->absmax);
|
||||
noise->teleport_time = level.time;
|
||||
noise->last_sound_time = level.time;
|
||||
gi.linkentity(noise);
|
||||
}
|
||||
|
||||
|
@ -659,7 +676,7 @@ weapon_grenade_fire(edict_t *ent, qboolean held)
|
|||
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 8);
|
||||
AngleVectors(ent->client->v_angle, forward, right, NULL);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
timer = ent->client->grenade_time - level.time;
|
||||
speed = GRENADE_MINSPEED + (GRENADE_TIMER -
|
||||
|
@ -848,7 +865,7 @@ weapon_grenadelauncher_fire(edict_t *ent)
|
|||
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 8);
|
||||
AngleVectors(ent->client->v_angle, forward, right, NULL);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
@ -913,7 +930,7 @@ Weapon_RocketLauncher_Fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -1;
|
||||
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
fire_rocket(ent, start, forward, damage, 650, damage_radius, radius_damage);
|
||||
|
||||
/* send muzzle flash */
|
||||
|
@ -966,7 +983,7 @@ Blaster_Fire(edict_t *ent, vec3_t g_offset, int damage,
|
|||
AngleVectors(ent->client->v_angle, forward, right, NULL);
|
||||
VectorSet(offset, 24, 8, ent->viewheight - 8);
|
||||
VectorAdd(offset, g_offset, offset);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
@ -1200,7 +1217,7 @@ Machinegun_Fire(edict_t *ent)
|
|||
VectorAdd(ent->client->v_angle, ent->client->kick_angles, angles);
|
||||
AngleVectors(angles, forward, right, NULL);
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
fire_bullet(ent, start, forward, damage, kick,
|
||||
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
|
||||
MOD_MACHINEGUN);
|
||||
|
@ -1367,8 +1384,7 @@ Chaingun_Fire(edict_t *ent)
|
|||
r = 7 + crandom() * 4;
|
||||
u = crandom() * 4;
|
||||
VectorSet(offset, 0, r, u + ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset,
|
||||
forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
fire_bullet(ent, start, forward, damage, kick,
|
||||
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
|
||||
|
@ -1427,7 +1443,7 @@ weapon_shotgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
if (is_quad)
|
||||
{
|
||||
|
@ -1487,7 +1503,7 @@ weapon_supershotgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
if (is_quad)
|
||||
{
|
||||
|
@ -1499,10 +1515,35 @@ weapon_supershotgun_fire(edict_t *ent)
|
|||
v[YAW] = ent->client->v_angle[YAW] - 5;
|
||||
v[ROLL] = ent->client->v_angle[ROLL];
|
||||
AngleVectors(v, forward, NULL, NULL);
|
||||
|
||||
if (aimfix->value)
|
||||
{
|
||||
AngleVectors(v, forward, right, NULL);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
}
|
||||
|
||||
fire_shotgun(ent, start, forward, damage, kick, DEFAULT_SHOTGUN_HSPREAD,
|
||||
DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SSHOTGUN_COUNT / 2, MOD_SSHOTGUN);
|
||||
|
||||
v[YAW] = ent->client->v_angle[YAW] + 5;
|
||||
AngleVectors(v, forward, NULL, NULL);
|
||||
|
||||
if (aimfix->value)
|
||||
{
|
||||
AngleVectors(v, forward, right, NULL);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
}
|
||||
|
||||
fire_shotgun(ent, start, forward, damage, kick,
|
||||
DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD,
|
||||
DEFAULT_SSHOTGUN_COUNT / 2, MOD_SSHOTGUN);
|
||||
|
@ -1573,7 +1614,7 @@ weapon_railgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -3;
|
||||
|
||||
VectorSet(offset, 0, 7, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
fire_rail(ent, start, forward, damage, kick);
|
||||
|
||||
/* send muzzle flash */
|
||||
|
@ -1663,7 +1704,7 @@ weapon_bfg_fire(edict_t *ent)
|
|||
ent->client->v_dmg_time = level.time + DAMAGE_TIME;
|
||||
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
fire_bfg(ent, start, forward, damage, 400, damage_radius);
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
|
|
|
@ -319,11 +319,8 @@ anglemod(float a)
|
|||
return a;
|
||||
}
|
||||
|
||||
int i;
|
||||
vec3_t corners[2];
|
||||
|
||||
/*
|
||||
* This is the slow, general version
|
||||
/*
|
||||
* This is the slow, general version
|
||||
*/
|
||||
int
|
||||
BoxOnPlaneSide2(vec3_t emins, vec3_t emaxs, struct cplane_s *p)
|
||||
|
@ -441,7 +438,7 @@ BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, struct cplane_s *p)
|
|||
p->normal[2] * emaxs[2];
|
||||
break;
|
||||
default:
|
||||
dist1 = dist2 = 0;
|
||||
dist1 = dist2 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -666,31 +663,17 @@ COM_StripExtension(char *in, char *out)
|
|||
*out = 0;
|
||||
}
|
||||
|
||||
char *
|
||||
COM_FileExtension(char *in)
|
||||
const char *
|
||||
COM_FileExtension(const char *in)
|
||||
{
|
||||
static char exten[8];
|
||||
int i;
|
||||
const char *ext = strrchr(in, '.');
|
||||
|
||||
while (*in && *in != '.')
|
||||
{
|
||||
in++;
|
||||
}
|
||||
|
||||
if (!*in)
|
||||
if (!ext || ext == in)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
in++;
|
||||
|
||||
for (i = 0; i < 7 && *in; i++, in++)
|
||||
{
|
||||
exten[i] = *in;
|
||||
}
|
||||
|
||||
exten[i] = 0;
|
||||
return exten;
|
||||
return ext + 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -774,7 +757,7 @@ COM_DefaultExtension(char *path, const char *extension)
|
|||
|
||||
qboolean bigendien;
|
||||
|
||||
/* can't just use function pointers, or dll linkage can
|
||||
/* can't just use function pointers, or dll linkage can
|
||||
mess up when qcommon is included in multiple places */
|
||||
short (*_BigShort)(short l);
|
||||
short (*_LittleShort)(short l);
|
||||
|
@ -786,37 +769,37 @@ float (*_LittleFloat)(float l);
|
|||
short
|
||||
BigShort(short l)
|
||||
{
|
||||
return _BigShort(l);
|
||||
return _BigShort(l);
|
||||
}
|
||||
|
||||
short
|
||||
LittleShort(short l)
|
||||
{return
|
||||
_LittleShort(l);
|
||||
{return
|
||||
_LittleShort(l);
|
||||
}
|
||||
|
||||
int
|
||||
BigLong(int l)
|
||||
{
|
||||
return _BigLong(l);
|
||||
return _BigLong(l);
|
||||
}
|
||||
|
||||
int
|
||||
LittleLong(int l)
|
||||
{
|
||||
return _LittleLong(l);
|
||||
return _LittleLong(l);
|
||||
}
|
||||
|
||||
float
|
||||
BigFloat(float l)
|
||||
{
|
||||
return _BigFloat(l);
|
||||
return _BigFloat(l);
|
||||
}
|
||||
|
||||
float
|
||||
LittleFloat(float l)
|
||||
{
|
||||
return _LittleFloat(l);
|
||||
return _LittleFloat(l);
|
||||
}
|
||||
|
||||
short
|
||||
|
@ -907,7 +890,7 @@ Swap_Init(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* does a varargs printf into a temp buffer, so I don't
|
||||
* does a varargs printf into a temp buffer, so I don't
|
||||
* need to have varargs versions of all text functions.
|
||||
*/
|
||||
char *
|
||||
|
@ -1089,6 +1072,43 @@ Q_strcasecmp(char *s1, char *s2)
|
|||
return Q_strncasecmp(s1, s2, 99999);
|
||||
}
|
||||
|
||||
int
|
||||
Q_strlcpy(char *dst, const char *src, int size)
|
||||
{
|
||||
const char *s = src;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (size > 1)
|
||||
{
|
||||
*dst++ = *s;
|
||||
size--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
return s - src;
|
||||
}
|
||||
|
||||
int
|
||||
Q_strlcat(char *dst, const char *src, int size)
|
||||
{
|
||||
char *d = dst;
|
||||
|
||||
while (size > 0 && *d)
|
||||
{
|
||||
size--;
|
||||
d++;
|
||||
}
|
||||
|
||||
return (d - dst) + Q_strlcpy(d, src, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Com_sprintf(char *dest, int size, char *fmt, ...)
|
||||
{
|
||||
|
@ -1127,7 +1147,7 @@ char *
|
|||
Info_ValueForKey(char *s, char *key)
|
||||
{
|
||||
char pkey[512];
|
||||
static char value[2][512]; /* use two buffers so compares
|
||||
static char value[2][512]; /* use two buffers so compares
|
||||
work without stomping on each other */
|
||||
static int valueindex;
|
||||
char *o;
|
||||
|
@ -1237,7 +1257,7 @@ Info_RemoveKey(char *s, char *key)
|
|||
|
||||
if (!strcmp(key, pkey))
|
||||
{
|
||||
strcpy(start, s); /* remove this part */
|
||||
memmove(start, s, strlen(s) + 1); /* remove this part */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
BIN
tools/mkdir.exe
BIN
tools/mkdir.exe
Binary file not shown.
Loading…
Reference in a new issue