mirror of
https://github.com/yquake2/ctf.git
synced 2025-04-21 01:50:51 +00:00
Compare commits
No commits in common. "master" and "CTF_1_07" have entirely different histories.
19 changed files with 127 additions and 543 deletions
45
.github/workflows/linux_aarch64.yml
vendored
45
.github/workflows/linux_aarch64.yml
vendored
|
@ -1,45 +0,0 @@
|
|||
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
45
.github/workflows/linux_x86_64.yml
vendored
|
@ -1,45 +0,0 @@
|
|||
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
49
.github/workflows/macos.yml
vendored
|
@ -1,49 +0,0 @@
|
|||
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
56
.github/workflows/win32.yml
vendored
|
@ -1,56 +0,0 @@
|
|||
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
56
.github/workflows/win64.yml
vendored
|
@ -1,56 +0,0 @@
|
|||
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
|
12
CHANGELOG
12
CHANGELOG
|
@ -1,15 +1,3 @@
|
|||
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.
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
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)
|
||||
|
|
164
Makefile
164
Makefile
|
@ -6,58 +6,32 @@
|
|||
# #
|
||||
# Dependencies: #
|
||||
# - None, but you need a Quake II to play. #
|
||||
# While in theory every one should work #
|
||||
# Yamagi Quake II is recommended. #
|
||||
# While in theorie every one should work #
|
||||
# Yamagi Quake II ist recommended. #
|
||||
# #
|
||||
# Platforms: #
|
||||
# - FreeBSD #
|
||||
# - Linux #
|
||||
# - Mac OS X #
|
||||
# - OpenBSD #
|
||||
# - Windows #
|
||||
# - Windows #
|
||||
# ----------------------------------------------------- #
|
||||
|
||||
# Detect the OS
|
||||
ifdef SystemRoot
|
||||
YQ2_OSTYPE ?= Windows
|
||||
OSTYPE := Windows
|
||||
else
|
||||
YQ2_OSTYPE ?= $(shell uname -s)
|
||||
OSTYPE := $(shell uname -s)
|
||||
endif
|
||||
|
||||
|
||||
# Special case for MinGW
|
||||
ifneq (,$(findstring MINGW,$(YQ2_OSTYPE)))
|
||||
YQ2_OSTYPE := Windows
|
||||
endif
|
||||
|
||||
# Detect the architecture
|
||||
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
|
||||
# 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
|
||||
ifneq (,$(findstring MINGW,$(OSTYPE)))
|
||||
OSTYPE := Windows
|
||||
endif
|
||||
|
||||
# On Windows / MinGW $(CC) is undefined by default.
|
||||
ifeq ($(YQ2_OSTYPE),Windows)
|
||||
CC ?= gcc
|
||||
CC := gcc
|
||||
endif
|
||||
|
||||
# Detect the compiler
|
||||
|
@ -73,37 +47,35 @@ endif
|
|||
|
||||
# ----------
|
||||
|
||||
# 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
|
||||
# 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 -fwrapv -arch x86_64
|
||||
else
|
||||
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)
|
||||
CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \
|
||||
-Wall -pipe -g -MMD -fwrapv
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Switch off some annoying warnings.
|
||||
# Switch of some annoying warnings.
|
||||
ifeq ($(COMPILER), clang)
|
||||
# -Wno-missing-braces because otherwise clang complains
|
||||
# about totally valid 'vec3_t bla = {0}' constructs.
|
||||
|
@ -119,12 +91,17 @@ endif
|
|||
|
||||
# ----------
|
||||
|
||||
# Defines the operating system and architecture
|
||||
override CFLAGS += -DYQ2OSTYPE=\"$(YQ2_OSTYPE)\" -DYQ2ARCH=\"$(YQ2_ARCH)\"
|
||||
# Base LDFLAGS.
|
||||
ifeq ($(OSTYPE), Darwin)
|
||||
LDFLAGS := -shared -arch x86_64
|
||||
else ifeq ($(OSTYPE), Windows)
|
||||
LDFLAGS := -shared -static-libgcc
|
||||
else
|
||||
LDFLAGS := -shared -lm
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# 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')\"
|
||||
|
@ -132,44 +109,11 @@ 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.
|
||||
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
|
||||
override LDFLAGS += -lm
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Builds everything
|
||||
all: ctf
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# When make is invoked by "make VERBOSE=1" print
|
||||
# the compiler and linker commands.
|
||||
|
||||
|
@ -185,21 +129,21 @@ endif
|
|||
.PHONY : all clean ctf
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# Cleanup
|
||||
clean:
|
||||
@echo "===> CLEAN"
|
||||
${Q}rm -Rf build release
|
||||
|
||||
|
||||
# ----------
|
||||
|
||||
# The ctf game
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
ctf:
|
||||
@echo "===> Building game.dll"
|
||||
$(Q)mkdir -p release
|
||||
$(MAKE) release/game.dll
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
else ifeq ($(OSTYPE), Darwin)
|
||||
ctf:
|
||||
@echo "===> Building game.dylib"
|
||||
${Q}mkdir -p release
|
||||
|
@ -212,7 +156,7 @@ ctf:
|
|||
|
||||
release/game.so : CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
|
||||
build/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
$(Q)mkdir -p $(@D)
|
||||
|
@ -246,7 +190,7 @@ CTF_OBJS_ = \
|
|||
src/player/trail.o \
|
||||
src/player/view.o \
|
||||
src/player/weapon.o \
|
||||
src/shared/shared.o
|
||||
src/shared/shared.o
|
||||
|
||||
# ----------
|
||||
|
||||
|
@ -265,18 +209,18 @@ CTF_DEPS= $(CTF_OBJS:.o=.d)
|
|||
|
||||
# ----------
|
||||
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
release/game.dll : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
$(Q)$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(CTF_OBJS)
|
||||
else ifeq ($(OSTYPE), Darwin)
|
||||
release/game.dylib : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
${Q}$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
${Q}$(CC) $(LDFLAGS) -o $@ $(CTF_OBJS)
|
||||
else
|
||||
release/game.so : $(CTF_OBJS)
|
||||
@echo "===> LD $@"
|
||||
$(Q)$(CC) -o $@ $(CTF_OBJS) $(LDFLAGS)
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(CTF_OBJS)
|
||||
endif
|
||||
|
||||
|
||||
# ----------
|
||||
|
|
32
README
Normal file
32
README
Normal file
|
@ -0,0 +1,32 @@
|
|||
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
66
README.md
|
@ -1,66 +0,0 @@
|
|||
# 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)
|
|
@ -1718,7 +1718,8 @@ 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, offset, f, r, start);
|
||||
P_ProjectSource(self->owner->client, self->owner->s.origin,
|
||||
offset, f, r, start);
|
||||
|
||||
VectorSubtract(start, self->owner->s.origin, offset);
|
||||
|
||||
|
@ -1902,7 +1903,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
|
|
@ -77,8 +77,6 @@ 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);
|
||||
|
|
|
@ -334,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_TEAM2));
|
||||
CTFTeamName(CTF_TEAM1));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -204,9 +204,6 @@ InitGame(void)
|
|||
/* dm map list */
|
||||
sv_maplist = gi.cvar("sv_maplist", "", 0);
|
||||
|
||||
/* others */
|
||||
aimfix = gi.cvar("aimfix", "0", CVAR_ARCHIVE);
|
||||
|
||||
/* items */
|
||||
InitItems();
|
||||
|
||||
|
|
|
@ -168,11 +168,11 @@ SV_FilterPacket(char *from)
|
|||
{
|
||||
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||
{
|
||||
return (filterban->value != 0);
|
||||
return (int)filterban->value;
|
||||
}
|
||||
}
|
||||
|
||||
return (filterban->value == 0);
|
||||
return (int)!filterban->value;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -541,8 +541,6 @@ extern cvar_t *flood_waitdelay;
|
|||
|
||||
extern cvar_t *sv_maplist;
|
||||
|
||||
extern cvar_t *aimfix;
|
||||
|
||||
#define world (&g_edicts[0])
|
||||
|
||||
/* item spawnflags */
|
||||
|
@ -762,7 +760,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(edict_t *ent, vec3_t distance,
|
||||
void P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance,
|
||||
vec3_t forward, vec3_t right, vec3_t result);
|
||||
void Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
||||
int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames,
|
||||
|
|
|
@ -36,21 +36,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#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;
|
||||
typedef enum {false, true} qboolean;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
|
|
|
@ -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(edict_t *ent)
|
||||
SP_info_player_intermission(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ SP_info_player_intermission(edict_t *ent)
|
|||
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)
|
||||
|
@ -1727,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,12 +33,10 @@ static byte is_silenced;
|
|||
void weapon_grenade_fire(edict_t *ent, qboolean held);
|
||||
|
||||
void
|
||||
P_ProjectSource(edict_t *ent, vec3_t distance,
|
||||
P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance,
|
||||
vec3_t forward, vec3_t right, vec3_t result)
|
||||
{
|
||||
gclient_t *client = ent->client;
|
||||
float *point = ent->s.origin;
|
||||
vec3_t _distance;
|
||||
vec3_t _distance;
|
||||
|
||||
VectorCopy(distance, _distance);
|
||||
|
||||
|
@ -52,21 +50,6 @@ P_ProjectSource(edict_t *ent, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -676,7 +659,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
timer = ent->client->grenade_time - level.time;
|
||||
speed = GRENADE_MINSPEED + (GRENADE_TIMER -
|
||||
|
@ -865,7 +848,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
@ -930,7 +913,7 @@ Weapon_RocketLauncher_Fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -1;
|
||||
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
fire_rocket(ent, start, forward, damage, 650, damage_radius, radius_damage);
|
||||
|
||||
/* send muzzle flash */
|
||||
|
@ -983,7 +966,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
VectorScale(forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
@ -1217,7 +1200,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
fire_bullet(ent, start, forward, damage, kick,
|
||||
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
|
||||
MOD_MACHINEGUN);
|
||||
|
@ -1384,7 +1367,8 @@ Chaingun_Fire(edict_t *ent)
|
|||
r = 7 + crandom() * 4;
|
||||
u = crandom() * 4;
|
||||
VectorSet(offset, 0, r, u + ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset,
|
||||
forward, right, start);
|
||||
|
||||
fire_bullet(ent, start, forward, damage, kick,
|
||||
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
|
||||
|
@ -1443,7 +1427,7 @@ weapon_shotgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
if (is_quad)
|
||||
{
|
||||
|
@ -1503,7 +1487,7 @@ weapon_supershotgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
if (is_quad)
|
||||
{
|
||||
|
@ -1515,35 +1499,10 @@ 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);
|
||||
|
@ -1614,7 +1573,7 @@ weapon_railgun_fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = -3;
|
||||
|
||||
VectorSet(offset, 0, 7, ent->viewheight - 8);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
fire_rail(ent, start, forward, damage, kick);
|
||||
|
||||
/* send muzzle flash */
|
||||
|
@ -1704,7 +1663,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, offset, forward, right, start);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
fire_bfg(ent, start, forward, damage, 400, damage_radius);
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
|
|
Loading…
Reference in a new issue