mirror of
https://github.com/yquake2/rogue.git
synced 2025-04-20 09:10:49 +00:00
Compare commits
158 commits
ROGUE_2_07
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
71d4b88ddf | ||
|
3ab00e4b92 | ||
|
7997219c85 | ||
|
358b497d16 | ||
|
6cb21cfe13 | ||
|
e84a19865d | ||
|
89320081fb | ||
|
abca9f7e82 | ||
|
5fc769f8cf | ||
|
fca183f43a | ||
|
bc833a17e8 | ||
|
830ad45774 | ||
|
61f1fdbbfd | ||
|
7cf6cad6ac | ||
|
45a7d82156 | ||
|
982d100bb0 | ||
|
f9dd3be7e7 | ||
|
3fd777fb2e | ||
|
2e2cb4fc1f | ||
|
19014a3c85 | ||
|
e2fcef5efc | ||
|
8a05565cfc | ||
|
b26f8e590b | ||
|
b886ea5bac | ||
|
3c92e9a30f | ||
|
145ed6ea89 | ||
|
acad845a6f | ||
|
bea9dc85ff | ||
|
8baa9d35b0 | ||
|
95a40eef13 | ||
|
15ac078a88 | ||
|
c3968e2534 | ||
|
b3654f4d27 | ||
|
a9c73a4ebb | ||
|
bd0019db85 | ||
|
f0a8e88abc | ||
|
db15317c90 | ||
|
3cb024b7b0 | ||
|
dfafc40af9 | ||
|
56b0e0cdc2 | ||
|
dd31f0377a | ||
|
c299a53a45 | ||
|
8ea7bcd495 | ||
|
1c52428172 | ||
|
ae187b3c63 | ||
|
10927dddaf | ||
|
772e396fb5 | ||
|
8e6edc5ac6 | ||
|
cb66a3cc14 | ||
|
2469740598 | ||
|
92a00c9f5d | ||
|
631e27190d | ||
|
890b42a318 | ||
|
70c4c50951 | ||
|
66100386e7 | ||
|
84fdbe057b | ||
|
16eee95bb8 | ||
|
452ad99821 | ||
|
c78a7358d3 | ||
|
dd0f1a8a61 | ||
|
391128e0ac | ||
|
8319109c9f | ||
|
15c531c300 | ||
|
0742bc24d7 | ||
|
46660b8902 | ||
|
2ad53a679f | ||
|
71b5f5cf95 | ||
|
c8914dd482 | ||
|
9d46ec85fd | ||
|
306beceb0c | ||
|
352e81481a | ||
|
004ff57649 | ||
|
4a9c7f897e | ||
|
f762ee6116 | ||
|
5d767c6b30 | ||
|
a9412c91b9 | ||
|
ff834f7a58 | ||
|
fc0ffbcc91 | ||
|
e2ac13dae4 | ||
|
9922dd88bb | ||
|
a4747d3d8d | ||
|
5ed36196b7 | ||
|
0dda457eb5 | ||
|
fb2f6bd3b5 | ||
|
f15c5c57a2 | ||
|
d64a15f535 | ||
|
3bb2602f5b | ||
|
eff7705812 | ||
|
678eee9bc7 | ||
|
2f76831f1c | ||
|
213b14e16a | ||
|
2246a943bf | ||
|
6b9331ea5f | ||
|
7bf2454901 | ||
|
6de4a9ce77 | ||
|
15ffab8518 | ||
|
1ca53f3118 | ||
|
43a5a3fc23 | ||
|
ca5e278670 | ||
|
e7642db54d | ||
|
c083b7c66c | ||
|
72a6f98730 | ||
|
20da96d0ab | ||
|
f63c952103 | ||
|
7d1007ea1e | ||
|
ee6164cbce | ||
|
2dd8c74dfd | ||
|
d272c24706 | ||
|
8cba5293a0 | ||
|
fb1ebf960e | ||
|
222438d738 | ||
|
f90991db4d | ||
|
ea57b889b6 | ||
|
73beecec44 | ||
|
19a6d805a9 | ||
|
6cc225d670 | ||
|
6b6e536f79 | ||
|
ab882a163f | ||
|
397fdd77d5 | ||
|
25b453f1b8 | ||
|
3bccc4bd79 | ||
|
98afa3a90d | ||
|
d1ddda04ea | ||
|
46362a3bb4 | ||
|
cc6bf7dd5f | ||
|
e4a467e9c9 | ||
|
503a8af5b2 | ||
|
f0ebf1addc | ||
|
a395fadf07 | ||
|
ce21ad2c16 | ||
|
a000d06300 | ||
|
9fd0bab374 | ||
|
a4fba01b97 | ||
|
b0303c1098 | ||
|
f2c4d1b0b0 | ||
|
0d2d20fc6e | ||
|
b92383eff9 | ||
|
e8f8a1309c | ||
|
9dfd9de811 | ||
|
6820b0cad1 | ||
|
cfd660abc3 | ||
|
221171831b | ||
|
964895b760 | ||
|
1cd49ad20b | ||
|
d8ee6ce10f | ||
|
2cfdfee43d | ||
|
73fd162dbe | ||
|
09f9cf8f61 | ||
|
fc18bfa568 | ||
|
0fc06c4fc9 | ||
|
95e432d604 | ||
|
e640c899c1 | ||
|
03a7d77127 | ||
|
8dd1007284 | ||
|
7e4fd68416 | ||
|
f0793d17f8 | ||
|
7bf7eff184 | ||
|
a1786d614e |
69 changed files with 50393 additions and 2008 deletions
46
.github/workflows/linux_aarch64.yml
vendored
Normal file
46
.github/workflows/linux_aarch64.yml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
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_arm:
|
||||
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-rogue-linux_aarch64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-rogue-linux_aarch64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/mapfixes publish/quake2-rogue-linux_aarch64-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-rogue-linux_aarch64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-rogue-linux_aarch64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-rogue-linux_aarch64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
46
.github/workflows/linux_x86_64.yml
vendored
Normal file
46
.github/workflows/linux_x86_64.yml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
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-rogue-linux_x86_64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-rogue-linux_x86_64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/mapfixes publish/quake2-rogue-linux_x86_64-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-rogue-linux_x86_64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-rogue-linux_x86_64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-rogue-linux_x86_64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
50
.github/workflows/macos.yml
vendored
Normal file
50
.github/workflows/macos.yml
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
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-rogue-macos-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-rogue-macos-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/mapfixes publish/quake2-rogue-macos-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-rogue-macos-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-rogue-macos-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-rogue-macos-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
57
.github/workflows/win32.yml
vendored
Normal file
57
.github/workflows/win32.yml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
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-rogue-win32-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-rogue-win32-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/mapfixes publish/quake2-rogue-win32-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-rogue-win32-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-rogue-win32-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-rogue-win32-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
57
.github/workflows/win64.yml
vendored
Normal file
57
.github/workflows/win64.yml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
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-rogue-win64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-rogue-win64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/mapfixes publish/quake2-rogue-win64-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-rogue-win64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-rogue-win64-${{github.sha}}/misc/docs/README.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-rogue-win64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
66
CHANGELOG
66
CHANGELOG
|
@ -1,3 +1,69 @@
|
|||
Ground Zero 2.12 to 2.13
|
||||
- Add weapon preview to the `cycleweap` command (by protocultor)
|
||||
- Fix leaking temporary spawnflags into entities spawned mid-level. (by
|
||||
BjossiAlfreds)
|
||||
|
||||
Ground Zero 2.11 to 2.12
|
||||
- Implement `g_quick_weap`. If set to 1, both weapprev and weapnext
|
||||
commands will count how many times they have been called, making
|
||||
possible to skip weapons by quickly tapping one of these keys. (by
|
||||
protocultor)
|
||||
- Work around naggy help icons. (by BjossiAlfreds)
|
||||
- Implement `g_monsterfootsteps` (by 0lvin)
|
||||
|
||||
Ground Zero 2.10 to 2.11
|
||||
- Relicense under GPL2.
|
||||
- Fix Entity used itself in rbase1 and other minor fixes. (by
|
||||
BjossiAlfreds)
|
||||
- Some fixes for rsewer1. (by BjossiAlfreds)
|
||||
- Fix minor AI glitches with turrets (by BjossiAlfreds)
|
||||
- Fixed nagging help message in rhangar2. (by BjossiAlfreds)
|
||||
- Fixed gunner grenade duck code running twice. (by BjossiAlfreds)
|
||||
- Fixed wrong Tank muzzle flash. (by BjossiAlfreds)
|
||||
- Implement `g_swap_speed`. This allows to skip frames of "putting down
|
||||
weapon" and "raising weapon" animations, speeding them up. (by
|
||||
protocultor)
|
||||
- Several fixes to makron (by BjossiAlfreds)
|
||||
- Fixed stand-ground gladiators not attacking at certain range. (by
|
||||
BjossiAlfreds)
|
||||
- Fixed monsters seeing players during intermissions. (by BjossiAlfreds)
|
||||
|
||||
Ground Zero 2.09 to 2.10
|
||||
- Implement faster weapon switching with the new 'cycleweap' command.
|
||||
(by protocultor).
|
||||
- Fixes pusher delta yaw manipulation. This fixes the infamous bug were
|
||||
a player standing on a blocked elevator gets turned around (by
|
||||
skuller).
|
||||
- Fix several coop related bugs with the powercubes. (by BjossiAlfreds)
|
||||
- A way better fix for dead bodies obstructing elevators or falling
|
||||
through the worldmodel. (by BjossiAlfreds)
|
||||
- Fix items already in water playing a splash sound at level start. (by
|
||||
BjossiAlfreds)
|
||||
|
||||
Ground Zero 2.08 to 2.09
|
||||
- Refine the 'g_footstep' cvar to match Quake II itself.
|
||||
- Implement 'g_machinegun_norecoil'. The cvar is cheat protected. (by
|
||||
De-Seppe)
|
||||
- Update the entity files for rmine1, rsewer2 and rware2, fixing some
|
||||
smaller map bugs. (by BjossiAlfreds and Dremor8484)
|
||||
- Fix soldiers never showing their pain skins as long as they're alive.
|
||||
(by BjossiAlfreds)
|
||||
- Implement the 'prefweap' command to select a weapon by priority. (by
|
||||
protocultor)
|
||||
|
||||
Ground Zero 2.07 to 2.08
|
||||
- Fix wrong sound for some items when activated. (by BjossiAlfreds)
|
||||
- Port the 'aimfix' cvar. (by Mitchell Richters)
|
||||
- Port the 'coop_pickup_weapons' and 'coop_elevator_delay' cvars.
|
||||
- Fix a long standing crash occuring when exploding projectiles like
|
||||
grenates or rockets generate sound targets and a least one monster
|
||||
starts moving to one of that targets.
|
||||
- Add a cvar `g_footsteps` to control the generation of footstep sound.
|
||||
- Move several hard coded map fixes to entity files. Add newly
|
||||
discovered mapfixes to the entity files. (by BjossiAlfreds)
|
||||
- Fix several subtile gameplay and entity handling bug. (by
|
||||
BjossiAlfreds)
|
||||
|
||||
Ground Zero 2.06 to 2.07
|
||||
- Several fixes for subtile bugs (by BjossiAlfreds)
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
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)
|
||||
|
@ -19,13 +22,13 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fno-strict-aliasing -fwrapv")
|
|||
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
|
||||
# Operating system
|
||||
add_definitions(-DOSTYPE="${CMAKE_SYSTEM_NAME}")
|
||||
add_definitions(-DYQ2OSTYPE="${CMAKE_SYSTEM_NAME}")
|
||||
|
||||
# Architecture string
|
||||
string(REGEX REPLACE "amd64" "x86_64" ARCH "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
string(REGEX REPLACE "i.86" "i386" ARCH "${ARCH}")
|
||||
string(REGEX REPLACE "^arm.*" "arm" ARCH "${ARCH}")
|
||||
add_definitions(-DARCH="${ARCH}")
|
||||
string(REGEX REPLACE "amd64" "x86_64" YQ2_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
string(REGEX REPLACE "i.86" "i386" YQ2_ARCH "${YQ2_ARCH}")
|
||||
string(REGEX REPLACE "^arm.*" "arm" YQ2_ARCH "${YQ2_ARCH}")
|
||||
add_definitions(-DYQ2ARCH="${YQ2_ARCH}")
|
||||
|
||||
# Linker Flags
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
|
581
LICENSE
581
LICENSE
|
@ -1,327 +1,340 @@
|
|||
LIMITED PROGRAM SOURCE CODE LICENSE
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
This Limited Program Source Code License (the "Agreement") is between
|
||||
Id Software, Inc., a Texas corporation, (hereinafter "Id Software")
|
||||
and Licensee (as defined below) and is made effective beginning on
|
||||
the date you, the Licensee, download the Code, as defined below,
|
||||
(the "Effective Date"). BY DOWNLOADING THE CODE, AS DEFINED
|
||||
BELOW, YOU, THE LICENSEE, AGREE TO ALL THE TERMS AND CONDITIONS OF
|
||||
THIS AGREEMENT. YOU SHOULD READ THIS AGREEMENT CAREFULLY BEFORE
|
||||
DOWNLOADING THE CODE. EVERY PERSON IN POSSESSION OF AN AUTHORIZED
|
||||
COPY, AS DEFINED BELOW, OF THE CODE SHALL BE SUBJECT TO THE TERMS
|
||||
AND CONDITIONS OF THIS AGREEMENT.
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
R E C I T A L S
|
||||
Preamble
|
||||
|
||||
WHEREAS, Id Software is the owner and developer of the computer software
|
||||
program source code accompanied by this Agreement (the "Code");
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
WHEREAS, Id Software desires to license certain limited non-exclusive
|
||||
rights regarding the Code to Licensee; and
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
WHEREAS, Licensee desires to receive a limited license for such rights.
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
T E R M S A N D C O N D I T I O N S
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
NOW, THEREFORE, for and in consideration of the mutual premises
|
||||
contained herein and for other good and valuable consideration,
|
||||
the receipt and sufficiency of which is hereby acknowledged, the
|
||||
undersigned parties do hereby agree as follows:
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
1. Definitions. The parties hereto agree the following definitions
|
||||
shall apply to this Agreement:
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
a. "Authorized Copy" shall mean a copy of the Code obtained by
|
||||
Authorized Means, as defined below. A copy of the Code is not
|
||||
an "Authorized Copy" unless it is accompanied by a copy of this
|
||||
Agreement and obtained by Authorized Means. A Modified Copy,
|
||||
as defined below, is not an Authorized Copy;
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
b. "Authorized Means" shall mean obtaining an Authorized Copy only
|
||||
by downloading the Authorized Copy from Id Software's Internet web
|
||||
site or from another web site authorized or approved by Id Software
|
||||
for such purposes or by obtaining an Authorized Copy by electronic
|
||||
means via the Internet;
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
c. "Code" shall mean the computer software program source code
|
||||
which accompanies this Agreement and includes Code included within
|
||||
any Modified Copy and which is the code that constitutes the
|
||||
Authorized Copy;
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
d. "Game" shall mean QUAKE II;
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
e. "Licensee" shall mean you, the person who is in possession of
|
||||
an Authorized Copy by Authorized Means; and
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
f. "Modified Copy" shall mean a copy of the Code first obtained
|
||||
by Authorized Means which is subsequently modified by Licensee,
|
||||
as provided in paragraph 2. below.
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. Grant of Rights. Subject to the terms and provisions of this
|
||||
Agreement, Id Software hereby grants to Licensee and Licensee hereby
|
||||
accepts, a limited, world-wide (except as otherwise provided herein),
|
||||
non-exclusive, non-transferable, and non-assignable license to: (i)
|
||||
use the Authorized Copy and the Modified Copy, as defined above, for
|
||||
the development by Licensee of extra levels operable with the Game (the
|
||||
"Extra Levels"); (ii) incorporate all or a portion of the Authorized Copy
|
||||
and the Modified Copy within the Extra Levels; (iii) distribute by way
|
||||
of a sublicense limited by the terms of this Agreement, free of charge
|
||||
and at no cost, the Authorized Copy and the Modified Copy to the extent
|
||||
such Modified Copy and such Authorized Copy, or a portion thereof, is
|
||||
included within the Extra Levels; (iv) distribute by way of a sublicense
|
||||
limited by the terms of this Agreement, free of charge and at no cost, by
|
||||
electronic transmission via the Internet only the Authorized Copy without
|
||||
any alteration or modification along with a copy of this Agreement which
|
||||
must always accompany the Authorized Copy; (v) modify the Authorized Copy
|
||||
in order to create a Modified Copy, as defined above; and (vi) distribute
|
||||
the Modified Copy by way of a sublicense limited by the terms of this
|
||||
Agreement, free of charge and at no cost, by electronic transmission via
|
||||
the Internet only. Each person or entity who/which receives a copy of
|
||||
the Code shall be subject to the terms of this Agreement but, no rights
|
||||
are granted to any person or entity who/which obtains, receives, or is
|
||||
in possession of any copy of the Code by other than Authorized Means.
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
3. Reservation of Rights and Prohibitions. Id Software expressly
|
||||
reserves all rights not granted herein. Licensee shall not make any use
|
||||
of the trademarks relating to the Game or Id Software (the "Trademarks").
|
||||
Any use by Licensee of the Authorized Copy or the Modified Copy not
|
||||
expressly permitted in paragraph 2. above is expressly prohibited and
|
||||
any such unauthorized use shall constitute a material breach of this
|
||||
Agreement by Licensee. Any use of the Code, whether included within
|
||||
a Modified Copy or otherwise, and/or the Authorized Copy not permitted
|
||||
in this Agreement shall constitute an infringement or violation of Id
|
||||
Software's copyright in the Code. Licensee shall not copy, reproduce,
|
||||
manufacture or distribute (free of charge or otherwise) the Authorized
|
||||
Copy or the Modified Copy in any tangible media, including, without
|
||||
limitation, a CD ROM. Licensee shall not commercially exploit by sale,
|
||||
lease, rental or otherwise the Authorized Copy or the Modified Copy
|
||||
whether included within Extra Levels or otherwise. Licensee shall not
|
||||
commercially exploit by sale, lease, rental or otherwise any Extra Levels
|
||||
developed by the use of the Code, whether in whole or in part. Licensee
|
||||
is not receiving any rights hereunder regarding the Game, the Trademarks
|
||||
or any audio-visual elements, artwork, sound, music, images, characters,
|
||||
or other element of the Game. Licensee may modify the Authorized Copy in
|
||||
order to create a Modified Copy, as noted above, but all sublicensees who
|
||||
receive the Modified Copy shall not receive any rights to commercially
|
||||
exploit or to make any other use of the Code included therein except the
|
||||
right to use such Code for such sublicensee's personal entertainment. By
|
||||
way of example and not exclusion, a sublicensee for the Modified Copy
|
||||
shall not further modify the Code within the Modified Copy. Only the
|
||||
Licensee who obtains the Code by Authorized Means shall be permitted to
|
||||
modify such Code on the terms as described in this Agreement.
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
4. Additional Obligations. In addition to the obligations of Licensee
|
||||
otherwise set forth in this Agreement, during the Term, and thereafter
|
||||
where specified, Licensee agrees that:
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
a. Licensee will not attack or challenge the ownership by Id
|
||||
Software of the Code, the Authorized Copy, the Game, the Trademarks,
|
||||
or any copyright, patent or trademark or other intellectual property
|
||||
right related thereto and Licensee will not attack or challenge
|
||||
the validity of the license granted hereunder during the Term or
|
||||
thereafter; and
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
b. Licensee will promptly inform Id Software of any unauthorized
|
||||
use of the Code, the Authorized Copy, the Trademarks, or the Game,
|
||||
or any portions thereof, and will reasonably assist Id Software
|
||||
in the enforcement of all rights Id Software may have against such
|
||||
unauthorized users.
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
5. Ownership. Title to and all ownership rights in and to the Code,
|
||||
whether included within the Modified Copy, the Authorized Copy or
|
||||
otherwise, the Game, the Authorized Copy, and the Trademarks and the
|
||||
copyrights, trade secrets, trademarks, patents and all other intellectual
|
||||
property rights related thereto shall remain with Id Software which shall
|
||||
have the exclusive right to protect the same by copyright or otherwise.
|
||||
Licensee shall have no ownership rights in or to the Game, the Code,
|
||||
the Authorized Copy or the Trademarks. Licensee acknowledges that
|
||||
Licensee, by this Agreement, is only receiving a limited license to use
|
||||
the Authorized Copy, as specified in paragraph 2. of this Agreement.
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
6. Compliance with Applicable Laws. In exercising Licensee's
|
||||
limited rights hereunder, Licensee shall comply with all applicable
|
||||
laws, [including, without limitation, 22 U.S.C., section 2778 and 22
|
||||
U.S.C. C.F.R. Parts 120-130 (1995)] regulations, ordinances and statutes,
|
||||
including, but not limited to, the import/export laws and regulations
|
||||
of the United States and its governmental and regulatory agencies
|
||||
(including, without limitation, the Bureau of Export Administration
|
||||
and the U.S. Department of Commerce) and all applicable international
|
||||
treaties and laws.
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
7. Term and Termination.
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
a. The term of this Agreement and the license granted herein
|
||||
begins on the Effective Date and shall expire, without notice,
|
||||
on a date one (1) calendar year from the Effective Date (the "Term").
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
b. Either party may terminate this Agreement, for any reason or
|
||||
no reason, on thirty (30) days written notice to the other party.
|
||||
Termination will be effective on the thirtieth (30th) day following
|
||||
delivery of the notice of termination. Notwithstanding anything
|
||||
to the contrary herein, this Agreement shall immediately terminate,
|
||||
without the requirement of any notice from Id Software to Licensee,
|
||||
upon the occurrence of any of the following "Terminating Events":
|
||||
(i) if Licensee files a petition in bankruptcy; (ii) if Licensee
|
||||
makes an assignment for the benefit of creditors; (iii) if any
|
||||
bankruptcy proceeding or assignment for benefit of creditors is
|
||||
commenced against Licensee and not dismissed within sixty (60)
|
||||
days after the date of its commencement; (iv) the insolvency of
|
||||
Licensee; or (v) a breach, whether material or otherwise, of this
|
||||
Agreement by Licensee. Upon the occurrence of a Terminating Event,
|
||||
this Agreement and any and all rights hereunder shall terminate
|
||||
without prejudice to any rights or claims Id Software may have,
|
||||
and all rights granted hereunder shall revert, without notice,
|
||||
to and be vested in Id Software.
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
c. Termination or expiration of this Agreement shall not create
|
||||
any liability against Id Software and shall not relieve Licensee
|
||||
from any liability which arises prior to termination or expiration.
|
||||
Upon expiration or earlier termination of this Agreement, Licensee
|
||||
shall have no further right to exercise the rights licensed hereunder
|
||||
or otherwise acquired in relation to this Agreement.
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
8. Licensee's Warranties. Licensee warrants and represents that:
|
||||
(i) Licensee has full legal rights and authority to enter into and
|
||||
become bound by the terms of this Agreement; (ii) Licensee has full
|
||||
legal rights and authority to perform Licensee?s obligations hereunder;
|
||||
(iii) Licensee will comply, at all times during the Term, with all
|
||||
applicable laws, as set forth hereinabove; (iv) all modifications which
|
||||
Licensee performs on the Code in order to create the Modified Copy and
|
||||
all non-Id Software property included within Extra Levels shall not
|
||||
infringe against or misappropriate any third party rights, including,
|
||||
without limitation, copyrights and trade secrets; and (v) the use or
|
||||
non-use of all modifications which Licensee performs on the Code in order
|
||||
to create the Modified Copy and all non-Id Software property included
|
||||
within Extra Levels shall not infringe against or misappropriate any third
|
||||
party rights, including, without limitation, copyrights and trade secrets.
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
9. Indemnification. Licensee hereby agrees to indemnify, hold
|
||||
harmless and defend Id Software and Id Software's predecessors,
|
||||
successors, assigns, officers, directors, shareholders, employees,
|
||||
agents, representatives, licensees (but not including Licensee),
|
||||
sublicensees, distributors, attorneys and accountants (collectively,
|
||||
the "Id Related Parties") from and against any and all "Claims", which
|
||||
shall mean all damages, claims, losses, causes of action, liabilities,
|
||||
lawsuits, judgments and expenses (including, without limitation,
|
||||
reasonable attorneys' fees and expenses) arising from, relating to or in
|
||||
connection with (i) a breach of this Agreement by Licensee and/or (ii)
|
||||
Licensee's use or non-use of the Code, whether the Authorized Copy or
|
||||
whether a portion of the Code as may be included within the Modified
|
||||
Copy or within Extra Levels. Id Software agrees to notify Licensee
|
||||
of any such Claims within a reasonable time after Id Software learns
|
||||
of same. Licensee, at its own expense, shall defend Id Software and the
|
||||
Id Related Parties from and against any and all Claims. Id Software and
|
||||
the Id Related Parties reserve the right to participate in any defense
|
||||
of the Claims with counsel of their choice, and at their own expense.
|
||||
In the event Licensee fails to provide a defense, then Licensee shall be
|
||||
responsible for paying the attorneys' fees and expenses incurred by Id
|
||||
Software and the Id Related Parties regarding the defense of the Claims.
|
||||
Id Software and the Id Related Parties, as applicable, agree to reasonably
|
||||
assist in the defense of the Claims. No settlement by Licensee of any
|
||||
Claims shall be valid unless Licensee receives the prior written consent
|
||||
of Id Software and the Id Related Parties, as applicable, to any such
|
||||
settlement, with consent may be withheld in Id Software's and the Id
|
||||
Related Parties' sole discretion.
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
10. Limitation of Liability. UNDER NO CIRCUMSTANCES SHALL ID SOFTWARE
|
||||
BE LIABLE TO LICENSEE FOR ACTUAL, SPECIAL, INCIDENTAL, CONSEQUENTIAL
|
||||
OR PUNITIVE DAMAGES OR ANY OTHER DAMAGES, WHETHER OR NOT ID SOFTWARE
|
||||
RECEIVES NOTICE OF ANY SUCH DAMAGES.
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. Disclaimer of Warranties. ID SOFTWARE EXPRESSLY DISCLAIMS ALL
|
||||
WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, WITH REGARD TO THE CODE, THE AUTHORIZED COPY AND OTHERWISE.
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
12. Goodwill. Licensee recognizes the great value of the goodwill
|
||||
associated with the Game and the Trademarks, and acknowledges that such
|
||||
goodwill, now existing and hereafter created, exclusively belongs to Id
|
||||
Software and that the Trademarks have acquired a secondary meaning in
|
||||
the mind of the public.
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
13. Remedies. In the event of a breach of this Agreement by Id Software,
|
||||
Licensee's sole remedy shall be to terminate this Agreement by delivering
|
||||
written notice of termination to Id Software. In the event of a breach
|
||||
by Licensee of this Agreement, Id Software may pursue the remedies to
|
||||
which Id Software is entitled under applicable law and this Agreement.
|
||||
Licensee agrees that Licensee's unauthorized use of the Authorized
|
||||
Copy would immediately and irreparably damage Id Software, and in the
|
||||
event of such threatened or actual unauthorized use, Id Software shall
|
||||
be entitled to an injunctive order appropriately restraining and/or
|
||||
prohibiting such unauthorized use without the necessity of Id Software
|
||||
posting bond or other security. Pursuit of any remedy by Id Software
|
||||
shall not constitute a waiver of any other right or remedy of Id Software
|
||||
under this Agreement or under applicable law.
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
14. Choice of Law, Venue and Service of Process. This Agreement shall
|
||||
be construed in accordance with the laws of the State of Texas and
|
||||
applicable United States federal law and all claims and/or lawsuits
|
||||
in connection with this Agreement must be brought in Dallas County,
|
||||
Texas where exclusive venue shall lie. Licensee hereby agrees that
|
||||
service of process by certified mail to the address set forth below,
|
||||
with return receipt requested, shall constitute valid service of process
|
||||
upon Licensee. If for any reason Licensee has moved or cannot be validly
|
||||
served, then Licensee appoints the Secretary of State of the state of
|
||||
Texas to accept service of process on Licensee's behalf.
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
15. Delivery of Notices. Unless otherwise directed in writing by
|
||||
the parties, all notices given hereunder shall be sent to the last
|
||||
known address of addressee. All notices, requests, consents and other
|
||||
communications under this Agreement shall be in writing and shall be
|
||||
deemed to have been delivered on the date personally delivered or on the
|
||||
date deposited in the United States Postal Service, postage prepaid, by
|
||||
certified mail, return receipt requested, or telegraphed and confirmed,
|
||||
or delivered by electronic facsimile and confirmed. Any notice to Id
|
||||
Software shall also be sent to its counsel: D. Wade Cloud, Jr., Hiersche,
|
||||
Martens, Hayward, Drakeley & Urbach, P.C., 15303 Dallas Parkway, Suite
|
||||
700, LB 17, Dallas, Texas 75248.
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
16. No Partnership, Etc. This Agreement does not constitute and shall
|
||||
not be construed as constituting a partnership or joint venture between
|
||||
Id Software and Licensee. Neither party shall have any right to obligate
|
||||
or bind the other party in any manner whatsoever, and nothing herein
|
||||
contained shall give, or is intended to give, any rights of any kind to
|
||||
any third persons.
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
17. Entire agreement. This Agreement constitutes the entire
|
||||
understanding between Licensee and Id Software regarding the subject
|
||||
matter hereof. Each and every clause of this Agreement is severable from
|
||||
the whole and shall survive unless the entire Agreement is declared
|
||||
unenforceable. No prior or present agreements or representations
|
||||
between the parties hereto regarding the subject matter hereof shall be
|
||||
binding upon the parties hereto unless incorporated in this Agreement.
|
||||
No modification or change in this Agreement shall be valid or binding
|
||||
upon the parties hereto unless in writing and executed by the parties
|
||||
to be bound thereby.
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
18. Assignment. This Agreement shall bind and inure to the benefit of
|
||||
Id Software, its successors and assigns, and Id Software may assign its
|
||||
rights hereunder, in Id Software's sole discretion. This Agreement
|
||||
is personal to Licensee, and Licensee shall not assign, transfer,
|
||||
convey nor franchise its rights granted hereunder. As provided above,
|
||||
Licensee may sublicense Licensee's limited rights herein by transferring
|
||||
the Authorized Copy by Authorized Means. As noted, each sublicensee
|
||||
in possession of a copy of the Authorized Copy shall be subject to the
|
||||
terms and conditions of this Agreement.
|
||||
NO WARRANTY
|
||||
|
||||
19. Survival. The following provisions shall survive the expiration
|
||||
or earlier termination of this Agreement: paragraphs 5., 8., 9., 10.,
|
||||
11., 12., 13., 14., 15., 16., 17., 19., 20.a. and 20.b.
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
20. Miscellaneous.
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
a. All captions in this Agreement are intended solely for the
|
||||
convenience of the parties, and none shall effect the meaning or
|
||||
construction of any provision.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
b. The terms and conditions of this Agreement have been negotiated
|
||||
fully and freely among the parties. Accordingly, the preparation
|
||||
of this Agreement by counsel for a given party will not be material
|
||||
to the construction hereof, and the terms of this Agreement shall
|
||||
not be strictly construed against such party.
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
BY DOWNLOADING THE CODE, AS DEFINED ABOVE, YOU, THE LICENSEE, AGREE TO
|
||||
ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
February 12, 1998
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
|
156
Makefile
156
Makefile
|
@ -6,8 +6,8 @@
|
|||
# #
|
||||
# Dependencies: #
|
||||
# - None, but you need a Quake II to play. #
|
||||
# While in theorie every client should work #
|
||||
# Yamagi Quake II ist recommended. #
|
||||
# While in theory every client should work #
|
||||
# Yamagi Quake II is recommended. #
|
||||
# #
|
||||
# Platforms: #
|
||||
# - FreeBSD #
|
||||
|
@ -19,33 +19,45 @@
|
|||
|
||||
# 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,$(OSTYPE)))
|
||||
OSTYPE := Windows
|
||||
endif
|
||||
|
||||
# On Windows / MinGW $(CC) is undefined by default.
|
||||
ifeq ($(OSTYPE),Windows)
|
||||
CC := gcc
|
||||
ifneq (,$(findstring MINGW,$(YQ2_OSTYPE)))
|
||||
YQ2_OSTYPE := Windows
|
||||
endif
|
||||
|
||||
# Detect the architecture
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
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
|
||||
ARCH := $(PROCESSOR_ARCHITEW6432)
|
||||
YQ2_ARCH ?= $(PROCESSOR_ARCHITEW6432)
|
||||
else
|
||||
# 32 bit Windows
|
||||
ARCH := $(PROCESSOR_ARCHITECTURE)
|
||||
YQ2_ARCH ?= $(PROCESSOR_ARCHITECTURE)
|
||||
endif
|
||||
endif # windows but MINGW_CHOST not defined
|
||||
else
|
||||
# Normalize some abiguous ARCH strings
|
||||
ARCH := $(shell uname -m | sed -e 's/i.86/i386/' -e 's/amd64/x86_64/' -e 's/^arm.*/arm/')
|
||||
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
|
||||
|
||||
# On Windows / MinGW $(CC) is undefined by default.
|
||||
ifeq ($(YQ2_OSTYPE),Windows)
|
||||
CC ?= gcc
|
||||
endif
|
||||
|
||||
# Detect the compiler
|
||||
|
@ -61,30 +73,32 @@ 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 -fwrapv -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 := -std=gnu99 -O2 -fno-strict-aliasing -fomit-frame-pointer \
|
||||
-Wall -pipe -g -MMD -fwrapv
|
||||
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
|
||||
|
||||
# ----------
|
||||
|
@ -106,17 +120,47 @@ endif
|
|||
# ----------
|
||||
|
||||
# Defines the operating system and architecture
|
||||
CFLAGS += -DOSTYPE=\"$(OSTYPE)\" -DARCH=\"$(ARCH)\"
|
||||
override CFLAGS += -DYQ2OSTYPE=\"$(YQ2_OSTYPE)\" -DYQ2ARCH=\"$(YQ2_ARCH)\"
|
||||
|
||||
# ----------
|
||||
|
||||
# For reproduceable 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
|
||||
else ifeq ($(OSTYPE), Windows)
|
||||
LDFLAGS := -shared -static-libgcc
|
||||
LDFLAGS ?=
|
||||
|
||||
# It's a shared library.
|
||||
override LDFLAGS += -shared
|
||||
|
||||
# Required libaries
|
||||
ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
override LDFLAGS += -arch $(YQ2_ARCH)
|
||||
else ifeq ($(YQ2_OSTYPE), Windows)
|
||||
override LDFLAGS += -static-libgcc
|
||||
else
|
||||
LDFLAGS := -shared -lm
|
||||
override LDFLAGS += -lm
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
@ -136,12 +180,12 @@ Q := @
|
|||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# Phony targets
|
||||
.PHONY : all clean rogue
|
||||
|
||||
# ----------
|
||||
|
||||
|
||||
# Cleanup
|
||||
clean:
|
||||
@echo "===> CLEAN"
|
||||
|
@ -150,12 +194,12 @@ clean:
|
|||
# ----------
|
||||
|
||||
# The rogue game
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
rogue:
|
||||
@echo "===> Building game.dll"
|
||||
${Q}mkdir -p release
|
||||
$(MAKE) release/game.dll
|
||||
else ifeq ($(OSTYPE), Darwin)
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
rogue:
|
||||
@echo "===> Building game.dylib"
|
||||
${Q}mkdir -p release
|
||||
|
@ -238,11 +282,11 @@ ROGUE_OBJS_ = \
|
|||
src/savegame/savegame.o \
|
||||
src/shared/flash.o \
|
||||
src/shared/rand.o \
|
||||
src/shared/shared.o
|
||||
src/shared/shared.o
|
||||
|
||||
# ----------
|
||||
|
||||
# Rewrite pathes to our object directory
|
||||
# Rewrite paths to our object directory
|
||||
ROGUE_OBJS = $(patsubst %,build/%,$(ROGUE_OBJS_))
|
||||
|
||||
# ----------
|
||||
|
@ -257,18 +301,18 @@ ROGUE_DEPS= $(ROGUE_OBJS:.o=.d)
|
|||
|
||||
# ----------
|
||||
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
release/game.dll : $(ROGUE_OBJS)
|
||||
@echo "===> LD $@"
|
||||
${Q}$(CC) $(LDFLAGS) -o $@ $(ROGUE_OBJS)
|
||||
else ifeq ($(OSTYPE), Darwin)
|
||||
${Q}$(CC) -o $@ $(ROGUE_OBJS) $(LDFLAGS)
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
release/game.dylib : $(ROGUE_OBJS)
|
||||
@echo "===> LD $@"
|
||||
${Q}$(CC) $(LDFLAGS) -o $@ $(ROGUE_OBJS)
|
||||
${Q}$(CC) -o $@ $(ROGUE_OBJS) $(LDFLAGS)
|
||||
else
|
||||
release/game.so : $(ROGUE_OBJS)
|
||||
@echo "===> LD $@"
|
||||
${Q}$(CC) $(LDFLAGS) -o $@ $(ROGUE_OBJS)
|
||||
${Q}$(CC) -o $@ $(ROGUE_OBJS) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
|
41
README
41
README
|
@ -1,41 +0,0 @@
|
|||
This is a bugfixed version of id Software's Quake II missionpack
|
||||
"Ground Zero", developed by Rogue Software. Hundreds of bugs were
|
||||
fixed, this version should run much more stable than the old
|
||||
SDK version. While compatible with any Quake II client that uses
|
||||
the original unaltered mod API, the "Yamagi Quake II Client" is
|
||||
highly recommended to play the addon. 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. Create a subdirectory rogue/ in your quake2 directory.
|
||||
3. Copy pak0.pak and videos/ from the "Ground Zero" CD to
|
||||
the newly created directory rogue/.
|
||||
4. Copy release/game.so to rogue/.
|
||||
5. Start the game with "./quake2 +set game rogue"
|
||||
|
||||
Installation for OS X:
|
||||
----------------------
|
||||
1. Create a subdirectory rogue/ in your quake2 directory.
|
||||
2. Copy pak0.pak and videos/ from the "Ground Zero" CD to
|
||||
the newly created directory rogue/.
|
||||
3. Copy game.dynlib from the zip-archive to rogue/.
|
||||
4. Start the game with "quake2 +set game rogue"
|
||||
|
||||
If you want to compile 'rogue' 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. Create a subdirectory rogue\ in your quake2 directory.
|
||||
2. Copy pak0.pak and videos\ from the "Ground Zero" CD to
|
||||
the newly created directory rogue\.
|
||||
3. Copy game.dll from the zip-archive to rogue/.
|
||||
4. Start the game with "quake2.exe +set game rogue"
|
||||
|
||||
If you want to compile 'rogue' 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.
|
67
README.md
Normal file
67
README.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Ground Zero for Yamagi Quake II
|
||||
|
||||
Ground Zero for Yamagi Quake II is a bugfixed version of the second
|
||||
official missionpack released for Quake II. It's based upon the Quake
|
||||
II SDK source code and licensed under GPL version 2:
|
||||
|
||||
* [LICENSE](https://github.com/yquake2/rogue/blob/master/LICENSE)
|
||||
|
||||
Hundreds of bugs were fixed and some convenience features added. The
|
||||
missionpack 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 Ground Zero for Yamagi Quake II has community support
|
||||
for MacOS and most other unixoid operating systems, including NetBSD,
|
||||
OpenBSD and Solaris.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Ground Zero 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/rogue/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/rogue/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
|
||||
|
||||
Ground Zero 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/rogue/actions)
|
89
src/g_ai.c
89
src/g_ai.c
|
@ -503,7 +503,7 @@ FoundTarget(edict_t *self)
|
|||
level.sight_entity->light_level = 128;
|
||||
}
|
||||
|
||||
self->show_hostile = (int)level.time + 1; /* wake up other monsters */
|
||||
self->show_hostile = level.time + 1; /* wake up other monsters */
|
||||
|
||||
VectorCopy(self->enemy->s.origin, self->monsterinfo.last_sighting);
|
||||
self->monsterinfo.trail_time = level.time;
|
||||
|
@ -616,15 +616,11 @@ FindTarget(edict_t *self)
|
|||
else
|
||||
{
|
||||
client = level.sight_client;
|
||||
|
||||
if (!client)
|
||||
{
|
||||
return false; /* no clients to get mad at */
|
||||
}
|
||||
}
|
||||
|
||||
/* if the entity went away, forget it */
|
||||
if (!client->inuse)
|
||||
if (!client || !client->inuse ||
|
||||
(client->client && level.intermissiontime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -692,7 +688,7 @@ FindTarget(edict_t *self)
|
|||
|
||||
if (r == RANGE_NEAR)
|
||||
{
|
||||
if ((client->show_hostile < (int)level.time) && !infront(self, client))
|
||||
if ((client->show_hostile < level.time) && !infront(self, client))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1151,11 +1147,38 @@ ai_run_slide(edict_t *self, float distance)
|
|||
* or do something else used by
|
||||
* ai_run and ai_stand
|
||||
*/
|
||||
static qboolean
|
||||
hesDeadJim(const edict_t *self)
|
||||
{
|
||||
const edict_t *enemy = self->enemy;
|
||||
|
||||
if (!enemy || !enemy->inuse)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self->monsterinfo.aiflags & AI_MEDIC)
|
||||
{
|
||||
return (enemy->health > 0);
|
||||
}
|
||||
|
||||
if (enemy->client && level.intermissiontime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self->monsterinfo.aiflags & AI_BRUTAL)
|
||||
{
|
||||
return (enemy->health <= -80);
|
||||
}
|
||||
|
||||
return (enemy->health <= 0);
|
||||
}
|
||||
|
||||
qboolean
|
||||
ai_checkattack(edict_t *self, float dist)
|
||||
{
|
||||
vec3_t temp;
|
||||
qboolean hesDeadJim;
|
||||
qboolean retval;
|
||||
|
||||
if (!self)
|
||||
|
@ -1199,7 +1222,7 @@ ai_checkattack(edict_t *self, float dist)
|
|||
}
|
||||
else
|
||||
{
|
||||
self->show_hostile = (int)level.time + 1;
|
||||
self->show_hostile = level.time + 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1208,41 +1231,10 @@ ai_checkattack(edict_t *self, float dist)
|
|||
enemy_vis = false;
|
||||
|
||||
/* see if the enemy is dead */
|
||||
hesDeadJim = false;
|
||||
|
||||
if ((!self->enemy) || (!self->enemy->inuse))
|
||||
if (hesDeadJim(self))
|
||||
{
|
||||
hesDeadJim = true;
|
||||
}
|
||||
else if (self->monsterinfo.aiflags & AI_MEDIC)
|
||||
{
|
||||
if (self->enemy->health > 0)
|
||||
{
|
||||
hesDeadJim = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->monsterinfo.aiflags & AI_BRUTAL)
|
||||
{
|
||||
if (self->enemy->health <= -80)
|
||||
{
|
||||
hesDeadJim = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->enemy->health <= 0)
|
||||
{
|
||||
hesDeadJim = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hesDeadJim)
|
||||
{
|
||||
self->monsterinfo.aiflags &= ~AI_MEDIC;
|
||||
self->enemy = NULL;
|
||||
self->monsterinfo.aiflags &= ~AI_MEDIC;
|
||||
|
||||
if (self->oldenemy && (self->oldenemy->health > 0))
|
||||
{
|
||||
|
@ -1279,7 +1271,7 @@ ai_checkattack(edict_t *self, float dist)
|
|||
}
|
||||
}
|
||||
|
||||
self->show_hostile = (int)level.time + 1; /* wake up other monsters */
|
||||
self->show_hostile = level.time + 1; /* wake up other monsters */
|
||||
|
||||
/* check knowledge of enemy */
|
||||
enemy_vis = visible(self, self->enemy);
|
||||
|
@ -1596,8 +1588,15 @@ ai_run(edict_t *self, float dist)
|
|||
return;
|
||||
}
|
||||
|
||||
tempgoal = G_SpawnOptional();
|
||||
|
||||
if (!tempgoal)
|
||||
{
|
||||
M_MoveToGoal(self, dist);
|
||||
return;
|
||||
}
|
||||
|
||||
save = self->goalentity;
|
||||
tempgoal = G_Spawn();
|
||||
self->goalentity = tempgoal;
|
||||
|
||||
new = false;
|
||||
|
|
297
src/g_cmds.c
297
src/g_cmds.c
|
@ -728,12 +728,20 @@ Cmd_WeapPrev_f(edict_t *ent)
|
|||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl->pers.weapon)
|
||||
if (g_quick_weap->value && cl->newweapon)
|
||||
{
|
||||
it = cl->newweapon;
|
||||
}
|
||||
else if (cl->pers.weapon)
|
||||
{
|
||||
it = cl->pers.weapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
selected_weapon = ITEM_INDEX(cl->pers.weapon);
|
||||
selected_weapon = ITEM_INDEX(it);
|
||||
|
||||
/* scan for the next valid one */
|
||||
for (i = 1; i <= MAX_ITEMS; i++)
|
||||
|
@ -748,12 +756,7 @@ Cmd_WeapPrev_f(edict_t *ent)
|
|||
|
||||
it = &itemlist[index];
|
||||
|
||||
if (!it->use)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(it->flags & IT_WEAPON))
|
||||
if (!it->use || !(it->flags & IT_WEAPON))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -763,6 +766,12 @@ Cmd_WeapPrev_f(edict_t *ent)
|
|||
/* prevent scrolling through ALL weapons */
|
||||
if (cl->newweapon == it)
|
||||
{
|
||||
if (g_quick_weap->value)
|
||||
{
|
||||
cl->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(cl->newweapon->icon);
|
||||
cl->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS + ITEM_INDEX(cl->newweapon);
|
||||
cl->pickup_msg_time = level.time + 0.9f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -783,14 +792,22 @@ Cmd_WeapNext_f(edict_t *ent)
|
|||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl->pers.weapon)
|
||||
if (g_quick_weap->value && cl->newweapon)
|
||||
{
|
||||
it = cl->newweapon;
|
||||
}
|
||||
else if (cl->pers.weapon)
|
||||
{
|
||||
it = cl->pers.weapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
selected_weapon = ITEM_INDEX(cl->pers.weapon);
|
||||
selected_weapon = ITEM_INDEX(it);
|
||||
|
||||
/* scan for the next valid one */
|
||||
/* scan for the next valid one */
|
||||
for (i = 1; i <= MAX_ITEMS; i++)
|
||||
{
|
||||
/* prevent scrolling through ALL weapons */
|
||||
|
@ -803,12 +820,7 @@ Cmd_WeapNext_f(edict_t *ent)
|
|||
|
||||
it = &itemlist[index];
|
||||
|
||||
if (!it->use)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(it->flags & IT_WEAPON))
|
||||
if (!it->use || !(it->flags & IT_WEAPON))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -818,6 +830,12 @@ Cmd_WeapNext_f(edict_t *ent)
|
|||
/* prevent scrolling through ALL weapons */
|
||||
if (cl->newweapon == it)
|
||||
{
|
||||
if (g_quick_weap->value)
|
||||
{
|
||||
cl->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(cl->newweapon->icon);
|
||||
cl->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS + ITEM_INDEX(cl->newweapon);
|
||||
cl->pickup_msg_time = level.time + 0.9f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1073,14 +1091,81 @@ Cmd_Wave_f(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
static qboolean
|
||||
flooded(edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
int i;
|
||||
int num_msgs;
|
||||
int mx;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!deathmatch->value && !coop->value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
num_msgs = flood_msgs->value;
|
||||
if (num_msgs <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
mx = sizeof(cl->flood_when) / sizeof(cl->flood_when[0]);
|
||||
|
||||
if (num_msgs > mx)
|
||||
{
|
||||
gi.dprintf("flood_msgs lowered to max: 10\n");
|
||||
|
||||
num_msgs = mx;
|
||||
gi.cvar_forceset("flood_msgs", "10");
|
||||
}
|
||||
|
||||
if (level.time < cl->flood_locktill)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
|
||||
(int)(cl->flood_locktill - level.time));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
i = (cl->flood_whenhead - num_msgs) + 1;
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
i += mx;
|
||||
}
|
||||
|
||||
if (cl->flood_when[i] &&
|
||||
(level.time - cl->flood_when[i]) < flood_persecond->value)
|
||||
{
|
||||
cl->flood_locktill = level.time + flood_waitdelay->value;
|
||||
|
||||
gi.cprintf(ent, PRINT_CHAT,
|
||||
"Flood protection: You can't talk for %d seconds.\n",
|
||||
(int)flood_waitdelay->value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cl->flood_whenhead = (cl->flood_whenhead + 1) % mx;
|
||||
cl->flood_when[cl->flood_whenhead] = level.time;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
|
||||
{
|
||||
int i, j;
|
||||
int j;
|
||||
edict_t *other;
|
||||
char *p;
|
||||
char text[2048];
|
||||
gclient_t *cl;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
|
@ -1092,6 +1177,11 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
|
|||
return;
|
||||
}
|
||||
|
||||
if (flooded(ent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
|
||||
{
|
||||
team = false;
|
||||
|
@ -1133,39 +1223,6 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
|
|||
|
||||
strcat(text, "\n");
|
||||
|
||||
if (flood_msgs->value)
|
||||
{
|
||||
cl = ent->client;
|
||||
|
||||
if (level.time < cl->flood_locktill)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
|
||||
(int)(cl->flood_locktill - level.time));
|
||||
return;
|
||||
}
|
||||
|
||||
i = cl->flood_whenhead - flood_msgs->value + 1;
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
i = (sizeof(cl->flood_when) / sizeof(cl->flood_when[0])) + i;
|
||||
}
|
||||
|
||||
if (cl->flood_when[i] &&
|
||||
(level.time - cl->flood_when[i] < flood_persecond->value))
|
||||
{
|
||||
cl->flood_locktill = level.time + flood_waitdelay->value;
|
||||
gi.cprintf(ent, PRINT_CHAT,
|
||||
"Flood protection: You can't talk for %d seconds.\n",
|
||||
(int)flood_waitdelay->value);
|
||||
return;
|
||||
}
|
||||
|
||||
cl->flood_whenhead = (cl->flood_whenhead + 1) % (sizeof(cl->flood_when) /
|
||||
sizeof(cl->flood_when[0]));
|
||||
cl->flood_when[cl->flood_whenhead] = level.time;
|
||||
}
|
||||
|
||||
if (dedicated->value)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_CHAT, "%s", text);
|
||||
|
@ -1470,6 +1527,7 @@ cycle_weapon(edict_t *ent)
|
|||
int i;
|
||||
int start;
|
||||
int num_weaps;
|
||||
const char *weapname = NULL;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
|
@ -1486,11 +1544,20 @@ cycle_weapon(edict_t *ent)
|
|||
num_weaps = gi.argc();
|
||||
|
||||
/* find where we want to start the search for the next eligible weapon */
|
||||
if (cl->pers.weapon)
|
||||
if (cl->newweapon)
|
||||
{
|
||||
weapname = cl->newweapon->classname;
|
||||
}
|
||||
else if (cl->pers.weapon)
|
||||
{
|
||||
weapname = cl->pers.weapon->classname;
|
||||
}
|
||||
|
||||
if (weapname)
|
||||
{
|
||||
for (i = 1; i < num_weaps; i++)
|
||||
{
|
||||
if (Q_stricmp(cl->pers.weapon->classname, gi.argv(i)) == 0)
|
||||
if (Q_stricmp(weapname, gi.argv(i)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1570,6 +1637,120 @@ cycle_weapon(edict_t *ent)
|
|||
|
||||
void
|
||||
Cmd_CycleWeap_f(edict_t *ent)
|
||||
{
|
||||
gitem_t *weap;
|
||||
gclient_t *cl;
|
||||
int num_weaps;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
num_weaps = gi.argc();
|
||||
if (num_weaps <= 1)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "Usage: cycleweap classname1 classname2 .. classnameN\n");
|
||||
return;
|
||||
}
|
||||
|
||||
weap = cycle_weapon(ent);
|
||||
if (!weap) return;
|
||||
|
||||
cl = ent->client;
|
||||
if (cl->pers.inventory[ITEM_INDEX(weap)] <= 0)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "Out of item: %s\n", weap->pickup_name);
|
||||
return;
|
||||
}
|
||||
|
||||
weap->use(ent, weap);
|
||||
if (num_weaps > 3 && cl->newweapon == weap)
|
||||
{
|
||||
cl->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(weap->icon);
|
||||
cl->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS + ITEM_INDEX(weap);
|
||||
cl->pickup_msg_time = level.time + 0.7f;
|
||||
}
|
||||
}
|
||||
|
||||
static gitem_t *
|
||||
preferred_weapon(edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
gitem_t *noammo_fallback;
|
||||
gitem_t *noweap_fallback;
|
||||
gitem_t *weap;
|
||||
gitem_t *ammo;
|
||||
int i;
|
||||
int num_weaps;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num_weaps = gi.argc();
|
||||
noammo_fallback = NULL;
|
||||
noweap_fallback = NULL;
|
||||
|
||||
/* find the first eligible weapon in the list we can switch to */
|
||||
for (i = 1; i < num_weaps; i++)
|
||||
{
|
||||
weap = FindItemByClassname(gi.argv(i));
|
||||
|
||||
if (weap && (weap->flags & IT_WEAPON) && weap->use)
|
||||
{
|
||||
if (cl->pers.inventory[ITEM_INDEX(weap)] > 0)
|
||||
{
|
||||
if (weap->ammo)
|
||||
{
|
||||
ammo = FindItem(weap->ammo);
|
||||
if (ammo)
|
||||
{
|
||||
if (cl->pers.inventory[ITEM_INDEX(ammo)] >= get_ammo_usage(weap))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
|
||||
if (!noammo_fallback)
|
||||
{
|
||||
noammo_fallback = weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
else if (!noweap_fallback)
|
||||
{
|
||||
noweap_fallback = weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no weapon was found, the fallbacks will be used for
|
||||
printing the appropriate error message to the console
|
||||
*/
|
||||
|
||||
if (noammo_fallback)
|
||||
{
|
||||
return noammo_fallback;
|
||||
}
|
||||
|
||||
return noweap_fallback;
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_PrefWeap_f(edict_t *ent)
|
||||
{
|
||||
gitem_t *weap;
|
||||
|
||||
|
@ -1580,11 +1761,11 @@ Cmd_CycleWeap_f(edict_t *ent)
|
|||
|
||||
if (gi.argc() <= 1)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "Usage: cycleweap classname1 classname2 .. classnameN\n");
|
||||
gi.cprintf(ent, PRINT_HIGH, "Usage: prefweap classname1 classname2 .. classnameN\n");
|
||||
return;
|
||||
}
|
||||
|
||||
weap = cycle_weapon(ent);
|
||||
weap = preferred_weapon(ent);
|
||||
if (weap)
|
||||
{
|
||||
if (ent->client->pers.inventory[ITEM_INDEX(weap)] <= 0)
|
||||
|
@ -1758,6 +1939,10 @@ ClientCommand(edict_t *ent)
|
|||
{
|
||||
Cmd_CycleWeap_f(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "prefweap") == 0)
|
||||
{
|
||||
Cmd_PrefWeap_f(ent);
|
||||
}
|
||||
else /* anything that doesn't match a command will be a chat */
|
||||
{
|
||||
Cmd_Say_f(ent, false, true);
|
||||
|
|
|
@ -128,11 +128,6 @@ Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
|||
return;
|
||||
}
|
||||
|
||||
if (targ->health < -999)
|
||||
{
|
||||
targ->health = -999;
|
||||
}
|
||||
|
||||
/* Reset AI flag for being ducked. This fixes a corner case
|
||||
were the monster is ressurected by a medic and get's stuck
|
||||
in the next frame for mmove_t not matching the AI state. */
|
||||
|
@ -629,6 +624,24 @@ CheckTeamDamage(edict_t *targ, edict_t *attacker)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_knockback(edict_t *targ, vec3_t dir, float knockback, float scale)
|
||||
{
|
||||
vec3_t kvel;
|
||||
float mass;
|
||||
|
||||
if (!knockback)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mass = (targ->mass < 50) ? 50.0f : (float)targ->mass;
|
||||
|
||||
VectorNormalize2(dir, kvel);
|
||||
VectorScale(kvel, scale * (knockback / mass), kvel);
|
||||
VectorAdd(targ->velocity, kvel, targ->velocity);
|
||||
}
|
||||
|
||||
void
|
||||
T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
||||
vec3_t point, vec3_t normal, int damage, int knockback, int dflags,
|
||||
|
@ -731,8 +744,6 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
|||
te_sparks = TE_SPARKS;
|
||||
}
|
||||
|
||||
VectorNormalize(dir);
|
||||
|
||||
/* bonus damage for suprising a monster */
|
||||
if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) &&
|
||||
(attacker->client) && (!targ->enemy) && (targ->health > 0))
|
||||
|
@ -746,37 +757,14 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
|||
}
|
||||
|
||||
/* figure momentum add */
|
||||
if (!(dflags & DAMAGE_NO_KNOCKBACK))
|
||||
if (!(dflags & DAMAGE_NO_KNOCKBACK) &&
|
||||
(targ->movetype != MOVETYPE_NONE) &&
|
||||
(targ->movetype != MOVETYPE_BOUNCE) &&
|
||||
(targ->movetype != MOVETYPE_PUSH) &&
|
||||
(targ->movetype != MOVETYPE_STOP))
|
||||
{
|
||||
if ((knockback) && (targ->movetype != MOVETYPE_NONE) &&
|
||||
(targ->movetype != MOVETYPE_BOUNCE) &&
|
||||
(targ->movetype != MOVETYPE_PUSH) &&
|
||||
(targ->movetype != MOVETYPE_STOP))
|
||||
{
|
||||
vec3_t kvel;
|
||||
float mass;
|
||||
|
||||
if (targ->mass < 50)
|
||||
{
|
||||
mass = 50;
|
||||
}
|
||||
else
|
||||
{
|
||||
mass = targ->mass;
|
||||
}
|
||||
|
||||
if (targ->client && (attacker == targ))
|
||||
{
|
||||
/* the rocket jump hack... */
|
||||
VectorScale(dir, 1600.0 * (float)knockback / mass, kvel);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorScale(dir, 500.0 * (float)knockback / mass, kvel);
|
||||
}
|
||||
|
||||
VectorAdd(targ->velocity, kvel, targ->velocity);
|
||||
}
|
||||
apply_knockback (targ, dir, knockback,
|
||||
((client && attacker == targ) ? 1600.0f : 500.0f));
|
||||
}
|
||||
|
||||
take = damage;
|
||||
|
|
54
src/g_func.c
54
src/g_func.c
|
@ -664,6 +664,39 @@ Use_Plat(edict_t *ent, edict_t *other, edict_t *activator /* unused */)
|
|||
plat_go_down(ent);
|
||||
}
|
||||
|
||||
void
|
||||
wait_and_change_think(edict_t* ent)
|
||||
{
|
||||
void (*afterwaitfunc)(edict_t *) = ent->moveinfo.endfunc;
|
||||
ent->moveinfo.endfunc = NULL;
|
||||
afterwaitfunc(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* In coop mode, this waits for coop_elevator_delay seconds
|
||||
* before calling afterwaitfunc(ent); otherwise it just calls
|
||||
* afterwaitfunc(ent);
|
||||
*/
|
||||
static void
|
||||
wait_and_change(edict_t* ent, void (*afterwaitfunc)(edict_t *))
|
||||
{
|
||||
float waittime = coop_elevator_delay->value;
|
||||
if (coop->value && waittime > 0.0f)
|
||||
{
|
||||
if(ent->nextthink == 0)
|
||||
{
|
||||
ent->moveinfo.endfunc = afterwaitfunc;
|
||||
ent->think = wait_and_change_think;
|
||||
ent->nextthink = level.time + waittime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
afterwaitfunc(ent);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Touch_Plat_Center(edict_t *ent, edict_t *other, cplane_t *plane /* unsed */,
|
||||
csurface_t *surf /* unused */)
|
||||
|
@ -687,7 +720,7 @@ Touch_Plat_Center(edict_t *ent, edict_t *other, cplane_t *plane /* unsed */,
|
|||
|
||||
if (ent->moveinfo.state == STATE_BOTTOM)
|
||||
{
|
||||
plat_go_up(ent);
|
||||
wait_and_change(ent, plat_go_up);
|
||||
}
|
||||
else if (ent->moveinfo.state == STATE_TOP)
|
||||
{
|
||||
|
@ -2068,7 +2101,7 @@ door_go_down(edict_t *self)
|
|||
void
|
||||
door_go_up(edict_t *self, edict_t *activator)
|
||||
{
|
||||
if (!self || !activator)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2233,7 +2266,7 @@ door_use(edict_t *self, edict_t *other /* unused */, edict_t *activator)
|
|||
edict_t *ent;
|
||||
vec3_t center;
|
||||
|
||||
if (!self || !activator)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3410,13 +3443,22 @@ trigger_elevator_use(edict_t *self, edict_t *other,
|
|||
edict_t *activator /* unused */)
|
||||
{
|
||||
edict_t *target;
|
||||
edict_t *train;
|
||||
|
||||
if (!self || !other)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->movetarget->nextthink)
|
||||
train = self->movetarget;
|
||||
|
||||
if (!train || !train->inuse ||
|
||||
!train->classname || strcmp(train->classname, "func_train") != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (train->nextthink)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3436,8 +3478,8 @@ trigger_elevator_use(edict_t *self, edict_t *other,
|
|||
return;
|
||||
}
|
||||
|
||||
self->movetarget->target_ent = target;
|
||||
train_resume(self->movetarget);
|
||||
train->target_ent = target;
|
||||
train_resume(train);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -219,27 +219,6 @@ Pickup_Powerup(edict_t *ent, edict_t *other)
|
|||
{
|
||||
SetRespawn(ent, ent->item->quantity);
|
||||
}
|
||||
|
||||
if (((int)dmflags->value & DF_INSTANT_ITEMS) ||
|
||||
((ent->item->use == Use_Quad) &&
|
||||
(ent->spawnflags & DROPPED_PLAYER_ITEM)))
|
||||
{
|
||||
if ((ent->item->use == Use_Quad) &&
|
||||
(ent->spawnflags & DROPPED_PLAYER_ITEM))
|
||||
{
|
||||
quad_drop_timeout_hack =
|
||||
(ent->nextthink - level.time) / FRAMETIME;
|
||||
}
|
||||
|
||||
if (ent->item->use)
|
||||
{
|
||||
ent->item->use(other, ent->item);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf("Powerup has no use function!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -426,9 +405,9 @@ Pickup_Pack(edict_t *ent, edict_t *other)
|
|||
other->client->pers.max_slugs = 100;
|
||||
}
|
||||
|
||||
if (other->client->pers.max_flechettes < 200)
|
||||
if (other->client->pers.max_flechettes < 300)
|
||||
{
|
||||
other->client->pers.max_flechettes = 200;
|
||||
other->client->pers.max_flechettes = 300;
|
||||
}
|
||||
|
||||
if (g_disruptor->value)
|
||||
|
@ -788,18 +767,6 @@ Pickup_Sphere(edict_t *ent, edict_t *other)
|
|||
{
|
||||
SetRespawn(ent, ent->item->quantity);
|
||||
}
|
||||
|
||||
if (((int)dmflags->value & DF_INSTANT_ITEMS))
|
||||
{
|
||||
if (ent->item->use)
|
||||
{
|
||||
ent->item->use(other, ent->item);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf("Powerup has no use function!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1051,7 +1018,6 @@ Add_Ammo(edict_t *ent, gitem_t *item, int count)
|
|||
|
||||
if (item->tag == AMMO_BULLETS)
|
||||
{
|
||||
printf("1\n");
|
||||
max = ent->client->pers.max_bullets;
|
||||
}
|
||||
else if (item->tag == AMMO_SHELLS)
|
||||
|
@ -1088,7 +1054,6 @@ Add_Ammo(edict_t *ent, gitem_t *item, int count)
|
|||
}
|
||||
else if (item->tag == AMMO_DISRUPTOR)
|
||||
{
|
||||
printf("2\n");
|
||||
max = ent->client->pers.max_rounds;
|
||||
}
|
||||
else
|
||||
|
@ -1591,6 +1556,33 @@ Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane /* unused */, csurface_
|
|||
{
|
||||
gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
/* activate item instantly if appropriate */
|
||||
/* moved down here so activation sounds override the pickup sound */
|
||||
if (deathmatch->value)
|
||||
{
|
||||
if ((((int)dmflags->value & DF_INSTANT_ITEMS) &&
|
||||
(ent->item->flags & IT_INSTANT_USE)) ||
|
||||
((ent->item->use == Use_Quad) &&
|
||||
(ent->spawnflags & DROPPED_PLAYER_ITEM)))
|
||||
{
|
||||
if ((ent->item->use == Use_Quad) &&
|
||||
(ent->spawnflags & DROPPED_PLAYER_ITEM))
|
||||
{
|
||||
quad_drop_timeout_hack =
|
||||
(ent->nextthink - level.time) / FRAMETIME;
|
||||
}
|
||||
|
||||
if (ent->item->use)
|
||||
{
|
||||
ent->item->use(other, ent->item);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf("Powerup has no use function!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ent->spawnflags & ITEM_TARGETS_USED))
|
||||
|
@ -2098,7 +2090,7 @@ SpawnItem(edict_t *ent, gitem_t *item)
|
|||
|
||||
PrecacheItem(item);
|
||||
|
||||
if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0))
|
||||
if (coop->value && !(ent->spawnflags & ITEM_NO_TOUCH) && (strcmp(ent->classname, "key_power_cube") == 0))
|
||||
{
|
||||
ent->spawnflags |= (1 << (8 + level.power_cubes));
|
||||
level.power_cubes++;
|
||||
|
@ -2859,7 +2851,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP|IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -2881,7 +2873,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
300,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -2903,7 +2895,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -2925,7 +2917,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_STAY_COOP | IT_POWERUP,
|
||||
IT_STAY_COOP | IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -2947,7 +2939,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_STAY_COOP | IT_POWERUP,
|
||||
IT_STAY_COOP | IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -3059,7 +3051,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -3081,7 +3073,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -3124,7 +3116,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -3146,7 +3138,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
120,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -3168,7 +3160,7 @@ gitem_t itemlist[] = {
|
|||
2,
|
||||
60,
|
||||
NULL,
|
||||
IT_POWERUP,
|
||||
IT_POWERUP | IT_INSTANT_USE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
|
10
src/g_main.c
10
src/g_main.c
|
@ -23,6 +23,8 @@ edict_t *g_edicts;
|
|||
cvar_t *deathmatch;
|
||||
cvar_t *coop;
|
||||
cvar_t *coop_baseq2; /* treat spawnflags according to baseq2 rules */
|
||||
cvar_t *coop_elevator_delay;
|
||||
cvar_t *coop_pickup_weapons;
|
||||
cvar_t *dmflags;
|
||||
cvar_t *skill;
|
||||
cvar_t *fraglimit;
|
||||
|
@ -35,6 +37,9 @@ cvar_t *maxspectators;
|
|||
cvar_t *maxentities;
|
||||
cvar_t *g_select_empty;
|
||||
cvar_t *dedicated;
|
||||
cvar_t *g_footsteps;
|
||||
cvar_t *g_monsterfootsteps;
|
||||
cvar_t *g_fix_triggered;
|
||||
|
||||
cvar_t *filterban;
|
||||
|
||||
|
@ -70,6 +75,11 @@ cvar_t *randomrespawn;
|
|||
|
||||
cvar_t *g_disruptor;
|
||||
|
||||
cvar_t *aimfix;
|
||||
cvar_t *g_machinegun_norecoil;
|
||||
cvar_t *g_quick_weap;
|
||||
cvar_t *g_swap_speed;
|
||||
|
||||
void SpawnEntities(char *mapname, char *entities, char *spawnpoint);
|
||||
void ClientThink(edict_t *ent, usercmd_t *cmd);
|
||||
qboolean ClientConnect(edict_t *ent, char *userinfo);
|
||||
|
|
34
src/g_misc.c
34
src/g_misc.c
|
@ -178,14 +178,19 @@ ThrowGib(edict_t *self, char *gibname, int damage, int type)
|
|||
return;
|
||||
}
|
||||
|
||||
gibsthisframe++;
|
||||
|
||||
if (gibsthisframe > MAX_GIBS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gib = G_Spawn();
|
||||
gib = G_SpawnOptional();
|
||||
|
||||
if (!gib)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gibsthisframe++;
|
||||
|
||||
VectorScale(self->size, 0.5, size);
|
||||
VectorAdd(self->absmin, size, origin);
|
||||
|
@ -195,6 +200,7 @@ ThrowGib(edict_t *self, char *gibname, int damage, int type)
|
|||
|
||||
gi.setmodel(gib, gibname);
|
||||
gib->solid = SOLID_BBOX;
|
||||
gib->svflags = SVF_DEADMONSTER;
|
||||
gib->s.effects |= EF_GIB;
|
||||
gib->flags |= FL_NO_KNOCKBACK;
|
||||
gib->takedamage = DAMAGE_YES;
|
||||
|
@ -255,6 +261,10 @@ ThrowHead(edict_t *self, char *gibname, int damage, int type)
|
|||
self->targetname = NULL;
|
||||
self->die = gib_die;
|
||||
|
||||
// The entity still has the monsters clipmaks.
|
||||
// Reset it to MASK_SHOT to be on the save side.
|
||||
self->clipmask = MASK_SHOT;
|
||||
|
||||
if (type == GIB_ORGANIC)
|
||||
{
|
||||
self->movetype = MOVETYPE_TOSS;
|
||||
|
@ -313,6 +323,10 @@ ThrowClientHead(edict_t *self, int damage)
|
|||
self->s.sound = 0;
|
||||
self->flags |= FL_NO_KNOCKBACK;
|
||||
|
||||
// The entity still has the monsters clipmaks.
|
||||
// Reset it to MASK_SHOT to be on the save side.
|
||||
self->clipmask = MASK_SHOT;
|
||||
|
||||
self->movetype = MOVETYPE_BOUNCE;
|
||||
VelocityForDamage(damage, vd);
|
||||
VectorAdd(self->velocity, vd, self->velocity);
|
||||
|
@ -353,14 +367,20 @@ ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin)
|
|||
return;
|
||||
}
|
||||
|
||||
debristhisframe++;
|
||||
|
||||
if (debristhisframe > MAX_DEBRIS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chunk = G_Spawn();
|
||||
chunk = G_SpawnOptional();
|
||||
|
||||
if (!chunk)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
debristhisframe++;
|
||||
|
||||
VectorCopy(origin, chunk->s.origin);
|
||||
gi.setmodel(chunk, modelname);
|
||||
v[0] = 100 * crandom();
|
||||
|
@ -677,7 +697,7 @@ SP_info_null(edict_t *self)
|
|||
/*
|
||||
* QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
*
|
||||
* Used as a positional target for lightning.
|
||||
* Used as a positional target for lighting.
|
||||
*/
|
||||
void
|
||||
SP_info_notnull(edict_t *self)
|
||||
|
|
|
@ -872,6 +872,16 @@ monster_start(edict_t *self)
|
|||
self->spawnflags |= 1;
|
||||
}
|
||||
|
||||
if ((self->spawnflags & 2) && !self->targetname)
|
||||
{
|
||||
if (g_fix_triggered->value)
|
||||
{
|
||||
self->spawnflags &= ~2;
|
||||
}
|
||||
|
||||
gi.dprintf ("triggered %s at %s has no targetname\n", self->classname, vtos (self->s.origin));
|
||||
}
|
||||
|
||||
if ((!(self->monsterinfo.aiflags & AI_GOOD_GUY)) &&
|
||||
(!(self->monsterinfo.aiflags & AI_DO_NOT_COUNT)))
|
||||
{
|
||||
|
|
|
@ -1746,3 +1746,48 @@ monster_jump_finished(edict_t *self)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean
|
||||
blind_rocket_ok (edict_t *self, vec3_t start, vec3_t right, vec3_t target, float ofs,
|
||||
vec3_t dir)
|
||||
{
|
||||
trace_t tr;
|
||||
vec3_t vec;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT);
|
||||
|
||||
/* since all traces have the same start point this only needs one check */
|
||||
if (tr.startsolid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tr.allsolid && (tr.fraction >= 0.5f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
VectorMA(target, -ofs, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
tr = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (!tr.allsolid && (tr.fraction >= 0.5f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
VectorMA(target, ofs, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
tr = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
return !tr.allsolid && (tr.fraction >= 0.5f);
|
||||
}
|
||||
|
|
45
src/g_phys.c
45
src/g_phys.c
|
@ -19,7 +19,6 @@ typedef struct
|
|||
edict_t *ent;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
float deltayaw;
|
||||
} pushed_t;
|
||||
pushed_t pushed[MAX_EDICTS], *pushed_p;
|
||||
|
||||
|
@ -53,7 +52,10 @@ SV_TestEntityPosition(edict_t *ent)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (ent->clipmask)
|
||||
/* dead bodies are supposed to not be solid so lets
|
||||
ensure they only collide with BSP during pushmoves
|
||||
*/
|
||||
if (ent->clipmask && !(ent->svflags & SVF_DEADMONSTER))
|
||||
{
|
||||
mask = ent->clipmask;
|
||||
}
|
||||
|
@ -518,6 +520,17 @@ retry:
|
|||
|
||||
trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask);
|
||||
|
||||
/* startsolid treats different-content volumes
|
||||
as continuous, like the bbox of a monster/player
|
||||
and the floor of an elevator. So do another trace
|
||||
that only collides with BSP so that we make a best
|
||||
effort to keep these entities inside non-solid space
|
||||
*/
|
||||
if (trace.startsolid && (mask & ~MASK_SOLID))
|
||||
{
|
||||
trace = gi.trace (start, ent->mins, ent->maxs, end, ent, MASK_SOLID);
|
||||
}
|
||||
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
gi.linkentity(ent);
|
||||
|
||||
|
@ -606,12 +619,6 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
pushed_p->ent = pusher;
|
||||
VectorCopy(pusher->s.origin, pushed_p->origin);
|
||||
VectorCopy(pusher->s.angles, pushed_p->angles);
|
||||
|
||||
if (pusher->client)
|
||||
{
|
||||
pushed_p->deltayaw = pusher->client->ps.pmove.delta_angles[YAW];
|
||||
}
|
||||
|
||||
pushed_p++;
|
||||
|
||||
/* move the pusher to it's final position */
|
||||
|
@ -679,11 +686,6 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
/* try moving the contacted entity */
|
||||
VectorAdd(check->s.origin, move, check->s.origin);
|
||||
|
||||
if (check->client)
|
||||
{
|
||||
check->client->ps.pmove.delta_angles[YAW] += amove[YAW];
|
||||
}
|
||||
|
||||
/* figure movement due to the pusher's amove */
|
||||
VectorSubtract(check->s.origin, pusher->s.origin, org);
|
||||
org2[0] = DotProduct(org, forward);
|
||||
|
@ -732,11 +734,6 @@ SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
VectorCopy(p->origin, p->ent->s.origin);
|
||||
VectorCopy(p->angles, p->ent->s.angles);
|
||||
|
||||
if (p->ent->client)
|
||||
{
|
||||
p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw;
|
||||
}
|
||||
|
||||
gi.linkentity(p->ent);
|
||||
}
|
||||
|
||||
|
@ -893,6 +890,12 @@ SV_Physics_Toss(edict_t *ent)
|
|||
/* regular thinking */
|
||||
SV_RunThink(ent);
|
||||
|
||||
/* entities are very often freed during thinking */
|
||||
if (!ent->inuse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* if not a team captain, so movement will be handled elsewhere */
|
||||
if (ent->flags & FL_TEAMSLAVE)
|
||||
{
|
||||
|
@ -984,7 +987,11 @@ SV_Physics_Toss(edict_t *ent)
|
|||
|
||||
if (!wasinwater && isinwater)
|
||||
{
|
||||
gi.positioned_sound(old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
|
||||
/* don't play splash sound for entities already in water on level start */
|
||||
if (level.framenum > 3)
|
||||
{
|
||||
gi.positioned_sound(old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
|
||||
}
|
||||
}
|
||||
else if (wasinwater && !isinwater)
|
||||
{
|
||||
|
|
|
@ -897,6 +897,9 @@ SpawnEntities(const char *mapname, char *entities, const char *spawnpoint)
|
|||
ent->s.renderfx |= RF_IR_VISIBLE;
|
||||
}
|
||||
|
||||
/* in case the last entity in the entstring has spawntemp fields */
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
gi.dprintf("%i entities inhibited.\n", inhibit);
|
||||
|
||||
G_FindTeams();
|
||||
|
|
|
@ -158,11 +158,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
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
#define TARGET_HELP_PRIMARY 1
|
||||
#define TARGET_HELP_THINK_DELAY 0.3f
|
||||
|
||||
#define LASER_ON 0x0001
|
||||
#define LASER_RED 0x0002
|
||||
#define LASER_GREEN 0x0004
|
||||
|
@ -153,6 +156,50 @@ SP_target_speaker(edict_t *ent)
|
|||
|
||||
/* ========================================================== */
|
||||
|
||||
static void
|
||||
Target_Help_Apply(const char *msg, int is_primary)
|
||||
{
|
||||
char *curr;
|
||||
size_t sz;
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_primary)
|
||||
{
|
||||
curr = game.helpmessage1;
|
||||
sz = sizeof(game.helpmessage1);
|
||||
}
|
||||
else
|
||||
{
|
||||
curr = game.helpmessage2;
|
||||
sz = sizeof(game.helpmessage2);
|
||||
}
|
||||
|
||||
if (strcmp(curr, msg) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strlcpy(curr, msg, sz - 1);
|
||||
|
||||
game.helpchanged++;
|
||||
}
|
||||
|
||||
void
|
||||
Target_Help_Think(edict_t *ent)
|
||||
{
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Target_Help_Apply(ent->message, ent->spawnflags & TARGET_HELP_PRIMARY);
|
||||
ent->think = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Use_Target_Help(edict_t *ent, edict_t *other /* unused */, edict_t *activator /* unused */)
|
||||
{
|
||||
|
@ -161,16 +208,18 @@ Use_Target_Help(edict_t *ent, edict_t *other /* unused */, edict_t *activator /*
|
|||
return;
|
||||
}
|
||||
|
||||
if (ent->spawnflags & 1)
|
||||
if (level.time > TARGET_HELP_THINK_DELAY)
|
||||
{
|
||||
strncpy(game.helpmessage1, ent->message, sizeof(game.helpmessage2) - 1);
|
||||
Target_Help_Apply(ent->message, ent->spawnflags & TARGET_HELP_PRIMARY);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(game.helpmessage2, ent->message, sizeof(game.helpmessage1) - 1);
|
||||
/* The game is still pre-loading so delay the help message a bit,
|
||||
otherwise its changes to game structure will leak past save loads
|
||||
*/
|
||||
ent->think = Target_Help_Think;
|
||||
ent->nextthink = TARGET_HELP_THINK_DELAY;
|
||||
}
|
||||
|
||||
game.helpchanged++;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "header/local.h"
|
||||
|
||||
qboolean FindTarget(edict_t *self);
|
||||
void infantry_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage);
|
||||
void infantry_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
|
||||
void infantry_stand(edict_t *self);
|
||||
void monster_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void SpawnTargetingSystem(edict_t *turret);
|
||||
|
@ -419,7 +419,7 @@ turret_driver_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
self->target_ent->owner = NULL;
|
||||
self->target_ent->teammaster->owner = NULL;
|
||||
|
||||
infantry_die(self, inflictor, attacker, damage);
|
||||
infantry_die(self, inflictor, attacker, damage, point);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -270,7 +270,7 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
|||
edict_t *t;
|
||||
edict_t *master;
|
||||
|
||||
if (!ent || !activator)
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
|||
}
|
||||
|
||||
/* print the message */
|
||||
if ((ent->message) && !(activator->svflags & SVF_MONSTER))
|
||||
if (activator && (ent->message) && !(activator->svflags & SVF_MONSTER))
|
||||
{
|
||||
gi.centerprintf(activator, "%s", ent->message);
|
||||
|
||||
|
@ -330,6 +330,13 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
|||
}
|
||||
}
|
||||
|
||||
/* correct killcounter if a living monster gets killtargeted */
|
||||
if ((t->monsterinfo.checkattack || strcmp (t->classname, "turret_driver") == 0) &&
|
||||
!(t->monsterinfo.aiflags & (AI_GOOD_GUY|AI_DO_NOT_COUNT)) && t->deadflag != DEAD_DEAD)
|
||||
{
|
||||
level.killed_monsters++;
|
||||
}
|
||||
|
||||
G_FreeEdict(t);
|
||||
|
||||
if (!ent->inuse)
|
||||
|
@ -662,40 +669,66 @@ G_InitEdict(edict_t *e)
|
|||
}
|
||||
|
||||
/*
|
||||
* Either finds a free edict, or allocates a new one.
|
||||
* Try to avoid reusing an entity that was recently freed,
|
||||
* because it can cause the client to think the entity
|
||||
* morphed into something else instead of being removed
|
||||
* and recreated, which can cause interpolated angles and
|
||||
* bad trails.
|
||||
* Either finds a free edict, or allocates a
|
||||
* new one. Try to avoid reusing an entity
|
||||
* that was recently freed, because it can
|
||||
* cause the client to think the entity
|
||||
* morphed into something else instead of
|
||||
* being removed and recreated, which can
|
||||
* cause interpolated angles and bad trails.
|
||||
*/
|
||||
edict_t *
|
||||
G_Spawn(void)
|
||||
#define POLICY_DEFAULT 0
|
||||
#define POLICY_DESPERATE 1
|
||||
|
||||
static edict_t *
|
||||
G_FindFreeEdict(int policy)
|
||||
{
|
||||
int i;
|
||||
edict_t *e;
|
||||
|
||||
e = &g_edicts[(int)maxclients->value + 1];
|
||||
|
||||
for (i = maxclients->value + 1; i < globals.num_edicts; i++, e++)
|
||||
for (e = g_edicts + game.maxclients + 1 ; e < &g_edicts[globals.num_edicts] ; e++)
|
||||
{
|
||||
/* the first couple seconds of server time can involve a lot of
|
||||
freeing and allocating, so relax the replacement policy */
|
||||
if (!e->inuse &&
|
||||
((e->freetime < 2) || (level.time - e->freetime > 0.5)))
|
||||
freeing and allocating, so relax the replacement policy
|
||||
*/
|
||||
if (!e->inuse && (policy == POLICY_DESPERATE || e->freetime < 2.0f || (level.time - e->freetime) > 0.5f))
|
||||
{
|
||||
G_InitEdict(e);
|
||||
G_InitEdict (e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == game.maxentities)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
edict_t *
|
||||
G_SpawnOptional(void)
|
||||
{
|
||||
edict_t *e = G_FindFreeEdict (POLICY_DEFAULT);
|
||||
|
||||
if (e)
|
||||
{
|
||||
gi.error("ED_Alloc: no free edicts");
|
||||
return e;
|
||||
}
|
||||
|
||||
globals.num_edicts++;
|
||||
G_InitEdict(e);
|
||||
if (globals.num_edicts >= game.maxentities)
|
||||
{
|
||||
return G_FindFreeEdict (POLICY_DESPERATE);
|
||||
}
|
||||
|
||||
e = &g_edicts[globals.num_edicts++];
|
||||
G_InitEdict (e);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
edict_t *
|
||||
G_Spawn(void)
|
||||
{
|
||||
edict_t *e = G_SpawnOptional();
|
||||
|
||||
if (!e)
|
||||
gi.error ("ED_Alloc: no free edicts");
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
|
@ -981,7 +981,14 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
gi.sound(self, CHAN_VOICE, gi.soundindex("weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0);
|
||||
self->solid = SOLID_NOT;
|
||||
self->touch = NULL;
|
||||
VectorMA(self->s.origin, -1 * FRAMETIME, self->velocity, self->s.origin);
|
||||
|
||||
/* move it back a bit from walls so the effects aren't cut off */
|
||||
if (!other->takedamage)
|
||||
{
|
||||
VectorNormalize(self->velocity);
|
||||
VectorMA(self->s.origin, -40.0f, self->velocity, self->s.origin);
|
||||
}
|
||||
|
||||
VectorClear(self->velocity);
|
||||
self->s.modelindex = gi.modelindex("sprites/s_bfg3.sp2");
|
||||
self->s.frame = 0;
|
||||
|
@ -991,6 +998,8 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
self->nextthink = level.time + FRAMETIME;
|
||||
self->enemy = other;
|
||||
|
||||
gi.linkentity(self);
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_BFG_BIGEXPLOSION);
|
||||
gi.WritePosition(self->s.origin);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#define FL_TEAMSLAVE 0x00000400 /* not the first on the team */
|
||||
#define FL_NO_KNOCKBACK 0x00000800
|
||||
#define FL_POWER_ARMOR 0x00001000 /* power armor (if any) is active */
|
||||
#define FL_COOP_TAKEN 0x00002000 /* Another client has already taken it */
|
||||
#define FL_RESPAWN 0x80000000 /* used for item respawning */
|
||||
|
||||
#define FL_MECHANICAL 0x00002000 /* entity is mechanical, use sparks not blood */
|
||||
|
@ -232,6 +233,7 @@ typedef struct
|
|||
#define IT_POWERUP 0x00000020
|
||||
#define IT_MELEE 0x00000040
|
||||
#define IT_NOT_GIVEABLE 0x00000080 /* item can not be given */
|
||||
#define IT_INSTANT_USE 0x000000100 /* item is insta-used on pickup if dmflag is set */
|
||||
|
||||
/* gitem_t->weapmodel for weapons indicates model index */
|
||||
#define WEAP_BLASTER 1
|
||||
|
@ -583,6 +585,8 @@ extern cvar_t *maxentities;
|
|||
extern cvar_t *deathmatch;
|
||||
extern cvar_t *coop;
|
||||
extern cvar_t *coop_baseq2; /* treat spawnflags according to baseq2 rules */
|
||||
extern cvar_t *coop_elevator_delay;
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *dmflags;
|
||||
extern cvar_t *skill;
|
||||
extern cvar_t *fraglimit;
|
||||
|
@ -591,6 +595,9 @@ extern cvar_t *password;
|
|||
extern cvar_t *spectator_password;
|
||||
extern cvar_t *g_select_empty;
|
||||
extern cvar_t *dedicated;
|
||||
extern cvar_t *g_footsteps;
|
||||
extern cvar_t *g_monsterfootsteps;
|
||||
extern cvar_t *g_fix_triggered;
|
||||
|
||||
extern cvar_t *filterban;
|
||||
|
||||
|
@ -627,6 +634,11 @@ extern cvar_t *randomrespawn;
|
|||
|
||||
extern cvar_t *g_disruptor;
|
||||
|
||||
extern cvar_t *aimfix;
|
||||
extern cvar_t *g_machinegun_norecoil;
|
||||
extern cvar_t *g_quick_weap;
|
||||
extern cvar_t *g_swap_speed;
|
||||
|
||||
/* this is for the count of monsters */
|
||||
#define ENT_SLOTS_LEFT \
|
||||
(ent->monsterinfo.monster_slots - \
|
||||
|
@ -713,6 +725,7 @@ void G_UseTargets(edict_t *ent, edict_t *activator);
|
|||
void G_SetMovedir(vec3_t angles, vec3_t movedir);
|
||||
|
||||
void G_InitEdict(edict_t *e);
|
||||
edict_t *G_SpawnOptional(void);
|
||||
edict_t *G_Spawn(void);
|
||||
void G_FreeEdict(edict_t *e);
|
||||
|
||||
|
@ -955,6 +968,8 @@ edict_t *PickCoopTarget(edict_t *self);
|
|||
int CountPlayers(void);
|
||||
void monster_jump_start(edict_t *self);
|
||||
qboolean monster_jump_finished(edict_t *self);
|
||||
qboolean blind_rocket_ok (edict_t *self, vec3_t start, vec3_t right,
|
||||
vec3_t target, float ofs, vec3_t dir);
|
||||
|
||||
/* g_sphere.c */
|
||||
void Defender_Launch(edict_t *self);
|
||||
|
@ -1238,8 +1253,8 @@ struct edict_s
|
|||
int max_health;
|
||||
int gib_health;
|
||||
int deadflag;
|
||||
int show_hostile;
|
||||
|
||||
float show_hostile;
|
||||
float powerarmor_time;
|
||||
|
||||
char *map; /* target_changelevel */
|
||||
|
@ -1249,7 +1264,7 @@ struct edict_s
|
|||
int dmg;
|
||||
int radius_dmg;
|
||||
float dmg_radius;
|
||||
int sounds; /* make this a spawntemp var? */
|
||||
int sounds; /* now also used for player death sound aggregation */
|
||||
int count;
|
||||
|
||||
edict_t *chain;
|
||||
|
|
|
@ -18,8 +18,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)
|
||||
|
@ -204,7 +217,7 @@ float BigFloat(float l);
|
|||
float LittleFloat(float l);
|
||||
|
||||
void Swap_Init(void);
|
||||
char *va(char *format, ...);
|
||||
char *va(const char *format, ...);
|
||||
|
||||
/* ============================================= */
|
||||
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The berserker.
|
||||
*
|
||||
|
@ -15,8 +34,35 @@ static int sound_punch;
|
|||
static int sound_sight;
|
||||
static int sound_search;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
void berserk_fidget(edict_t *self);
|
||||
|
||||
void
|
||||
berserk_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("berserk/step1.wav");
|
||||
sound_step2 = gi.soundindex("berserk/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
berserk_sight(edict_t *self, edict_t *other)
|
||||
{
|
||||
|
@ -39,7 +85,7 @@ berserk_search(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_stand[] = {
|
||||
static mframe_t berserk_frames_stand[] = {
|
||||
{ai_stand, 0, berserk_fidget},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -47,11 +93,12 @@ mframe_t berserk_frames_stand[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_stand = {
|
||||
mmove_t berserk_move_stand =
|
||||
{
|
||||
FRAME_stand1,
|
||||
FRAME_stand5,
|
||||
berserk_frames_stand,
|
||||
NULL
|
||||
FRAME_stand5,
|
||||
berserk_frames_stand,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -65,7 +112,7 @@ berserk_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &berserk_move_stand;
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_stand_fidget[] = {
|
||||
static mframe_t berserk_frames_stand_fidget[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -88,7 +135,8 @@ mframe_t berserk_frames_stand_fidget[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_stand_fidget = {
|
||||
mmove_t berserk_move_stand_fidget =
|
||||
{
|
||||
FRAME_standb1,
|
||||
FRAME_standb20,
|
||||
berserk_frames_stand_fidget,
|
||||
|
@ -122,26 +170,27 @@ berserk_fidget(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_idle, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_walk[] = {
|
||||
static mframe_t berserk_frames_walk[] = {
|
||||
{ai_walk, 9.1, NULL},
|
||||
{ai_walk, 6.3, NULL},
|
||||
{ai_walk, 4.9, NULL},
|
||||
{ai_walk, 6.7, NULL},
|
||||
{ai_walk, 6.7, berserk_footstep},
|
||||
{ai_walk, 6.0, NULL},
|
||||
{ai_walk, 8.2, NULL},
|
||||
{ai_walk, 7.2, NULL},
|
||||
{ai_walk, 6.1, NULL},
|
||||
{ai_walk, 4.9, NULL},
|
||||
{ai_walk, 4.9, berserk_footstep},
|
||||
{ai_walk, 4.7, NULL},
|
||||
{ai_walk, 4.7, NULL},
|
||||
{ai_walk, 4.8, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_walk = {
|
||||
mmove_t berserk_move_walk =
|
||||
{
|
||||
FRAME_walkc1,
|
||||
FRAME_walkc11,
|
||||
berserk_frames_walk,
|
||||
NULL
|
||||
FRAME_walkc11,
|
||||
berserk_frames_walk,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -155,20 +204,21 @@ berserk_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &berserk_move_walk;
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_run1[] = {
|
||||
static mframe_t berserk_frames_run1[] = {
|
||||
{ai_run, 21, NULL},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 11, berserk_footstep},
|
||||
{ai_run, 21, NULL},
|
||||
{ai_run, 25, monster_done_dodge},
|
||||
{ai_run, 18, NULL},
|
||||
{ai_run, 18, berserk_footstep},
|
||||
{ai_run, 19, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_run1 = {
|
||||
mmove_t berserk_move_run1 =
|
||||
{
|
||||
FRAME_run1,
|
||||
FRAME_run6,
|
||||
berserk_frames_run1,
|
||||
NULL
|
||||
FRAME_run6,
|
||||
berserk_frames_run1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -214,7 +264,7 @@ berserk_swing(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_punch, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_attack_spike[] = {
|
||||
static mframe_t berserk_frames_attack_spike[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, berserk_swing},
|
||||
|
@ -225,11 +275,12 @@ mframe_t berserk_frames_attack_spike[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_attack_spike = {
|
||||
mmove_t berserk_move_attack_spike =
|
||||
{
|
||||
FRAME_att_c1,
|
||||
FRAME_att_c8,
|
||||
berserk_frames_attack_spike,
|
||||
berserk_run
|
||||
FRAME_att_c8,
|
||||
berserk_frames_attack_spike,
|
||||
berserk_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -246,10 +297,10 @@ berserk_attack_club(edict_t *self)
|
|||
fire_hit(self, aim, (5 + (rand() % 6)), 400);
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_attack_club[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
static mframe_t berserk_frames_attack_club[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, berserk_footstep},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, berserk_swing},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -261,11 +312,12 @@ mframe_t berserk_frames_attack_club[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_attack_club = {
|
||||
mmove_t berserk_move_attack_club =
|
||||
{
|
||||
FRAME_att_c9,
|
||||
FRAME_att_c20,
|
||||
berserk_frames_attack_club,
|
||||
berserk_run
|
||||
FRAME_att_c20,
|
||||
berserk_frames_attack_club,
|
||||
berserk_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -273,28 +325,29 @@ berserk_strike(edict_t *self)
|
|||
{
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_attack_strike[] = {
|
||||
{ai_move, 0, NULL},
|
||||
static mframe_t berserk_frames_attack_strike[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, berserk_footstep},
|
||||
{ai_move, 0, berserk_swing},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, berserk_strike},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, berserk_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 9.7, NULL},
|
||||
{ai_move, 13.6, NULL}
|
||||
{ai_move, 13.6, berserk_footstep}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_attack_strike = {
|
||||
mmove_t berserk_move_attack_strike =
|
||||
{
|
||||
FRAME_att_c21,
|
||||
FRAME_att_c34,
|
||||
berserk_frames_attack_strike,
|
||||
berserk_run
|
||||
FRAME_att_c34,
|
||||
berserk_frames_attack_strike,
|
||||
berserk_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -317,21 +370,22 @@ berserk_melee(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_pain1[] = {
|
||||
static mframe_t berserk_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_pain1 = {
|
||||
mmove_t berserk_move_pain1 =
|
||||
{
|
||||
FRAME_painc1,
|
||||
FRAME_painc4,
|
||||
berserk_frames_pain1,
|
||||
berserk_run
|
||||
FRAME_painc4,
|
||||
berserk_frames_pain1,
|
||||
berserk_run
|
||||
};
|
||||
|
||||
mframe_t berserk_frames_pain2[] = {
|
||||
static mframe_t berserk_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -354,15 +408,17 @@ mframe_t berserk_frames_pain2[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_pain2 = {
|
||||
mmove_t berserk_move_pain2 =
|
||||
{
|
||||
FRAME_painb1,
|
||||
FRAME_painb20,
|
||||
berserk_frames_pain2,
|
||||
berserk_run
|
||||
FRAME_painb20,
|
||||
berserk_frames_pain2,
|
||||
berserk_run
|
||||
};
|
||||
|
||||
void
|
||||
berserk_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
berserk_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -415,7 +471,7 @@ berserk_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_death1[] = {
|
||||
static mframe_t berserk_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -431,14 +487,15 @@ mframe_t berserk_frames_death1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_death1 = {
|
||||
mmove_t berserk_move_death1 =
|
||||
{
|
||||
FRAME_death1,
|
||||
FRAME_death13,
|
||||
berserk_frames_death1,
|
||||
berserk_dead
|
||||
FRAME_death13,
|
||||
berserk_frames_death1,
|
||||
berserk_dead
|
||||
};
|
||||
|
||||
mframe_t berserk_frames_death2[] = {
|
||||
static mframe_t berserk_frames_death2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -449,16 +506,17 @@ mframe_t berserk_frames_death2[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t berserk_move_death2 = {
|
||||
mmove_t berserk_move_death2 =
|
||||
{
|
||||
FRAME_deathc1,
|
||||
FRAME_deathc8,
|
||||
berserk_frames_death2,
|
||||
berserk_dead
|
||||
berserk_frames_death2,
|
||||
berserk_dead
|
||||
};
|
||||
|
||||
void
|
||||
berserk_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point)
|
||||
int damage, vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -473,15 +531,18 @@ berserk_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -562,7 +623,7 @@ berserk_jump_wait_land(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t berserk_frames_jump[] = {
|
||||
static mframe_t berserk_frames_jump[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -581,7 +642,7 @@ mmove_t berserk_move_jump = {
|
|||
berserk_run
|
||||
};
|
||||
|
||||
mframe_t berserk_frames_jump2[] = {
|
||||
static mframe_t berserk_frames_jump2[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
|
@ -674,6 +735,11 @@ SP_monster_berserk(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
/* pre-caches */
|
||||
sound_pain = gi.soundindex("berserk/berpain2.wav");
|
||||
sound_die = gi.soundindex("berserk/berdeth2.wav");
|
||||
|
|
|
@ -99,7 +99,7 @@ Boss2PredictiveRocket(edict_t *self)
|
|||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
monster_fire_rocket(self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_4);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Boss2Rocket(edict_t *self)
|
||||
|
@ -159,7 +159,7 @@ Boss2Rocket(edict_t *self)
|
|||
VectorMA(dir, -0.4, right, dir);
|
||||
VectorNormalize(dir);
|
||||
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
boss2_firebullet_right(edict_t *self)
|
||||
|
@ -222,7 +222,7 @@ Boss2MachineGun(edict_t *self)
|
|||
boss2_firebullet_right(self);
|
||||
}
|
||||
|
||||
mframe_t boss2_frames_stand[] = {
|
||||
static mframe_t boss2_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -253,7 +253,7 @@ mmove_t boss2_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_fidget[] = {
|
||||
static mframe_t boss2_frames_fidget[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -293,7 +293,7 @@ mmove_t boss2_move_fidget = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_walk[] = {
|
||||
static mframe_t boss2_frames_walk[] = {
|
||||
{ai_walk, 10, NULL},
|
||||
{ai_walk, 10, NULL},
|
||||
{ai_walk, 10, NULL},
|
||||
|
@ -323,7 +323,7 @@ mmove_t boss2_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_run[] = {
|
||||
static mframe_t boss2_frames_run[] = {
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
|
@ -353,7 +353,7 @@ mmove_t boss2_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_attack_pre_mg[] = {
|
||||
static mframe_t boss2_frames_attack_pre_mg[] = {
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
|
@ -373,7 +373,7 @@ mmove_t boss2_move_attack_pre_mg = {
|
|||
};
|
||||
|
||||
/* Loop this */
|
||||
mframe_t boss2_frames_attack_mg[] = {
|
||||
static mframe_t boss2_frames_attack_mg[] = {
|
||||
{ai_charge, 2, Boss2MachineGun},
|
||||
{ai_charge, 2, Boss2MachineGun},
|
||||
{ai_charge, 2, Boss2MachineGun},
|
||||
|
@ -389,7 +389,7 @@ mmove_t boss2_move_attack_mg = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_attack_post_mg[] = {
|
||||
static mframe_t boss2_frames_attack_post_mg[] = {
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
|
@ -404,7 +404,7 @@ mmove_t boss2_move_attack_post_mg = {
|
|||
boss2_run
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_attack_rocket[] = {
|
||||
static mframe_t boss2_frames_attack_rocket[] = {
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
|
@ -434,7 +434,7 @@ mmove_t boss2_move_attack_rocket = {FRAME_attack20,
|
|||
boss2_run
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_pain_heavy[] = {
|
||||
static mframe_t boss2_frames_pain_heavy[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -462,7 +462,7 @@ mmove_t boss2_move_pain_heavy = {
|
|||
boss2_run
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_pain_light[] = {
|
||||
static mframe_t boss2_frames_pain_light[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -476,7 +476,7 @@ mmove_t boss2_move_pain_light = {
|
|||
boss2_run
|
||||
};
|
||||
|
||||
mframe_t boss2_frames_death[] = {
|
||||
static mframe_t boss2_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -65,7 +65,7 @@ jorg_search(edict_t *self)
|
|||
}
|
||||
|
||||
/* stand */
|
||||
mframe_t jorg_frames_stand[] = {
|
||||
static mframe_t jorg_frames_stand[] = {
|
||||
{ai_stand, 0, jorg_idle},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -181,7 +181,7 @@ jorg_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &jorg_move_stand;
|
||||
}
|
||||
|
||||
mframe_t jorg_frames_run[] = {
|
||||
static mframe_t jorg_frames_run[] = {
|
||||
{ai_run, 17, jorg_step_left},
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
|
@ -206,7 +206,7 @@ mmove_t jorg_move_run = {
|
|||
};
|
||||
|
||||
/* walk */
|
||||
mframe_t jorg_frames_start_walk[] = {
|
||||
static mframe_t jorg_frames_start_walk[] = {
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
|
@ -221,7 +221,7 @@ mmove_t jorg_move_start_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_walk[] = {
|
||||
static mframe_t jorg_frames_walk[] = {
|
||||
{ai_walk, 17, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
|
@ -245,7 +245,7 @@ mmove_t jorg_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_end_walk[] = {
|
||||
static mframe_t jorg_frames_end_walk[] = {
|
||||
{ai_walk, 11, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
|
@ -290,7 +290,7 @@ jorg_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t jorg_frames_pain3[] = {
|
||||
static mframe_t jorg_frames_pain3[] = {
|
||||
{ai_move, -28, NULL},
|
||||
{ai_move, -6, NULL},
|
||||
{ai_move, -3, jorg_step_left},
|
||||
|
@ -325,7 +325,7 @@ mmove_t jorg_move_pain3 = {
|
|||
jorg_run
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_pain2[] = {
|
||||
static mframe_t jorg_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
|
@ -338,7 +338,7 @@ mmove_t jorg_move_pain2 = {
|
|||
jorg_run
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_pain1[] = {
|
||||
static mframe_t jorg_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
|
@ -351,7 +351,7 @@ mmove_t jorg_move_pain1 = {
|
|||
jorg_run
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_death1[] = {
|
||||
static mframe_t jorg_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -411,7 +411,7 @@ mmove_t jorg_move_death = {
|
|||
jorg_dead
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_attack2[] = {
|
||||
static mframe_t jorg_frames_attack2[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -434,7 +434,7 @@ mmove_t jorg_move_attack2 = {
|
|||
jorg_run
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_start_attack1[] = {
|
||||
static mframe_t jorg_frames_start_attack1[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -452,7 +452,7 @@ mmove_t jorg_move_start_attack1 = {
|
|||
jorg_attack1
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_attack1[] = {
|
||||
static mframe_t jorg_frames_attack1[] = {
|
||||
{ai_charge, 0, jorg_firebullet},
|
||||
{ai_charge, 0, jorg_firebullet},
|
||||
{ai_charge, 0, jorg_firebullet},
|
||||
|
@ -468,7 +468,7 @@ mmove_t jorg_move_attack1 = {
|
|||
jorg_reattack1
|
||||
};
|
||||
|
||||
mframe_t jorg_frames_end_attack1[] = {
|
||||
static mframe_t jorg_frames_end_attack1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -875,8 +875,8 @@ SP_monster_jorg(edict_t *self)
|
|||
|
||||
self->movetype = MOVETYPE_STEP;
|
||||
self->solid = SOLID_BBOX;
|
||||
self->s.modelindex = gi.modelindex("models/monsters/boss3/rider/tris.md2");
|
||||
self->s.modelindex2 = gi.modelindex("models/monsters/boss3/jorg/tris.md2");
|
||||
self->s.modelindex = gi.modelindex("models/monsters/boss3/jorg/tris.md2");
|
||||
self->s.modelindex2 = gi.modelindex("models/monsters/boss3/rider/tris.md2");
|
||||
VectorSet(self->mins, -80, -80, 0);
|
||||
VectorSet(self->maxs, 80, 80, 140);
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ makron_taunt(edict_t *self)
|
|||
}
|
||||
|
||||
/* stand */
|
||||
mframe_t makron_frames_stand[] = {
|
||||
static mframe_t makron_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -141,7 +141,7 @@ makron_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &makron_move_stand;
|
||||
}
|
||||
|
||||
mframe_t makron_frames_run[] = {
|
||||
static mframe_t makron_frames_run[] = {
|
||||
{ai_run, 3, makron_step_left},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
|
@ -227,19 +227,6 @@ makron_prerailgun(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_prerailgun, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t makron_frames_walk[] = {
|
||||
{ai_walk, 3, makron_step_left},
|
||||
{ai_walk, 12, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
{ai_walk, 8, makron_step_right},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 12, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 12, NULL}
|
||||
};
|
||||
|
||||
mmove_t makron_move_walk = {
|
||||
FRAME_walk204,
|
||||
FRAME_walk213,
|
||||
|
@ -276,7 +263,7 @@ makron_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t makron_frames_pain6[] = {
|
||||
static mframe_t makron_frames_pain6[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -313,7 +300,7 @@ mmove_t makron_move_pain6 = {
|
|||
makron_run
|
||||
};
|
||||
|
||||
mframe_t makron_frames_pain5[] = {
|
||||
static mframe_t makron_frames_pain5[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -327,7 +314,7 @@ mmove_t makron_move_pain5 = {
|
|||
makron_run
|
||||
};
|
||||
|
||||
mframe_t makron_frames_pain4[] = {
|
||||
static mframe_t makron_frames_pain4[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -341,7 +328,7 @@ mmove_t makron_move_pain4 = {
|
|||
makron_run
|
||||
};
|
||||
|
||||
mframe_t makron_frames_death2[] = {
|
||||
static mframe_t makron_frames_death2[] = {
|
||||
{ai_move, -15, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, -12, NULL},
|
||||
|
@ -446,7 +433,7 @@ mmove_t makron_move_death2 = {
|
|||
makron_dead
|
||||
};
|
||||
|
||||
mframe_t makron_frames_death3[] = {
|
||||
static mframe_t makron_frames_death3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -476,7 +463,7 @@ mmove_t makron_move_death3 = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t makron_frames_sight[] = {
|
||||
static mframe_t makron_frames_sight[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -524,7 +511,7 @@ makronBFG(edict_t *self)
|
|||
monster_fire_bfg(self, start, dir, 50, 300, 100, 300, MZ2_MAKRON_BFG);
|
||||
}
|
||||
|
||||
mframe_t makron_frames_attack3[] = {
|
||||
static mframe_t makron_frames_attack3[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -542,7 +529,7 @@ mmove_t makron_move_attack3 = {
|
|||
makron_run
|
||||
};
|
||||
|
||||
mframe_t makron_frames_attack4[] = {
|
||||
static mframe_t makron_frames_attack4[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -578,7 +565,7 @@ mmove_t makron_move_attack4 = {
|
|||
makron_run
|
||||
};
|
||||
|
||||
mframe_t makron_frames_attack5[] = {
|
||||
static mframe_t makron_frames_attack5[] = {
|
||||
{ai_charge, 0, makron_prerailgun},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -757,12 +744,6 @@ makron_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
void
|
||||
makron_sight(edict_t *self, edict_t *other /* unused */)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->monsterinfo.currentmove = &makron_move_sight;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -799,7 +780,14 @@ makron_torso_think(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->owner && self->owner->inuse && self->owner->deadflag != DEAD_DEAD)
|
||||
/* detach from the makron if the legs are gone completely */
|
||||
if (self->owner && (!self->owner->inuse || (self->owner->health <= self->owner->gib_health)))
|
||||
{
|
||||
self->owner = NULL;
|
||||
}
|
||||
|
||||
/* if the makron is revived the torso was put back on him */
|
||||
if (self->owner && self->owner->deadflag != DEAD_DEAD)
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
|
@ -824,24 +812,84 @@ makron_torso_think(edict_t *self)
|
|||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void
|
||||
makron_torso(edict_t *ent)
|
||||
static void
|
||||
makron_torso_origin(edict_t *self, edict_t *torso)
|
||||
{
|
||||
if (!ent)
|
||||
vec3_t v;
|
||||
trace_t tr;
|
||||
|
||||
AngleVectors(self->s.angles, v, NULL, NULL);
|
||||
VectorMA(self->s.origin, -84.0f, v, v);
|
||||
|
||||
tr = gi.trace(self->s.origin, torso->mins, torso->maxs, v, self, MASK_SOLID);
|
||||
|
||||
VectorCopy (tr.endpos, torso->s.origin);
|
||||
}
|
||||
|
||||
void
|
||||
makron_torso_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage /* unused */, vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (self->health > self->gib_health)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->solid = SOLID_NOT;
|
||||
VectorSet(ent->mins, -8, -8, 0);
|
||||
VectorSet(ent->maxs, 8, 8, 8);
|
||||
ent->s.frame = FRAME_death301;
|
||||
ent->s.modelindex = gi.modelindex("models/monsters/boss3/rider/tris.md2");
|
||||
ent->think = makron_torso_think;
|
||||
ent->nextthink = level.time + 2 * FRAMETIME;
|
||||
ent->s.sound = gi.soundindex("makron/spine.wav");
|
||||
gi.linkentity(ent);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_metal/tris.md2",
|
||||
damage, GIB_METALLIC);
|
||||
}
|
||||
|
||||
G_FreeEdict(self);
|
||||
}
|
||||
|
||||
void
|
||||
makron_torso(edict_t *self)
|
||||
{
|
||||
edict_t *torso;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
torso = G_SpawnOptional();
|
||||
|
||||
if (!torso)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(self->s.angles, torso->s.angles);
|
||||
VectorSet(torso->mins, -24, -24, 0);
|
||||
VectorSet(torso->maxs, 24, 24, 16);
|
||||
makron_torso_origin(self, torso);
|
||||
|
||||
torso->gib_health = -800;
|
||||
torso->takedamage = DAMAGE_YES;
|
||||
torso->die = makron_torso_die;
|
||||
torso->deadflag = DEAD_DEAD;
|
||||
|
||||
torso->owner = self;
|
||||
torso->movetype = MOVETYPE_TOSS;
|
||||
torso->solid = SOLID_BBOX;
|
||||
torso->svflags = SVF_MONSTER|SVF_DEADMONSTER;
|
||||
torso->clipmask = MASK_MONSTERSOLID;
|
||||
torso->s.frame = FRAME_death301;
|
||||
torso->s.modelindex = gi.modelindex("models/monsters/boss3/rider/tris.md2");
|
||||
torso->think = makron_torso_think;
|
||||
torso->nextthink = level.time + 2 * FRAMETIME;
|
||||
torso->s.sound = gi.soundindex("makron/spine.wav");
|
||||
|
||||
gi.linkentity(torso);
|
||||
}
|
||||
|
||||
/* death */
|
||||
|
@ -853,8 +901,8 @@ makron_dead(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
VectorSet(self->mins, -60, -60, 0);
|
||||
VectorSet(self->maxs, 60, 60, 72);
|
||||
VectorSet(self->mins, -48, -48, 0);
|
||||
VectorSet(self->maxs, 48, 48, 24);
|
||||
self->movetype = MOVETYPE_TOSS;
|
||||
self->svflags |= SVF_DEADMONSTER;
|
||||
self->nextthink = 0;
|
||||
|
@ -865,7 +913,6 @@ void
|
|||
makron_die(edict_t *self, edict_t *inflictor /* update */, edict_t *attacker /* update */,
|
||||
int damage, vec3_t point /* update */)
|
||||
{
|
||||
edict_t *tempent;
|
||||
int n;
|
||||
|
||||
if (!self)
|
||||
|
@ -905,12 +952,11 @@ makron_die(edict_t *self, edict_t *inflictor /* update */, edict_t *attacker /*
|
|||
self->deadflag = DEAD_DEAD;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
|
||||
tempent = G_Spawn();
|
||||
VectorCopy(self->s.origin, tempent->s.origin);
|
||||
VectorCopy(self->s.angles, tempent->s.angles);
|
||||
tempent->s.origin[1] -= 84;
|
||||
tempent->owner = self;
|
||||
makron_torso(tempent);
|
||||
makron_torso(self);
|
||||
|
||||
/* lower bbox since the torso is gone */
|
||||
self->maxs[2] = 64;
|
||||
gi.linkentity (self);
|
||||
|
||||
self->monsterinfo.currentmove = &makron_move_death2;
|
||||
}
|
||||
|
@ -1098,29 +1144,72 @@ void
|
|||
MakronSpawn(edict_t *self)
|
||||
{
|
||||
vec3_t vec;
|
||||
edict_t *player;
|
||||
edict_t *enemy;
|
||||
edict_t *oldenemy;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* spawning can mess with enemy state so clear it temporarily */
|
||||
enemy = self->enemy;
|
||||
self->enemy = NULL;
|
||||
|
||||
oldenemy = self->oldenemy;
|
||||
self->oldenemy = NULL;
|
||||
|
||||
SP_monster_makron(self);
|
||||
|
||||
/* jump at player */
|
||||
player = level.sight_client;
|
||||
|
||||
if (!player)
|
||||
if (self->think)
|
||||
{
|
||||
return;
|
||||
self->think(self);
|
||||
}
|
||||
|
||||
VectorSubtract(player->s.origin, self->s.origin, vec);
|
||||
self->s.angles[YAW] = vectoyaw(vec);
|
||||
VectorNormalize(vec);
|
||||
VectorMA(vec3_origin, 400, vec, self->velocity);
|
||||
self->velocity[2] = 200;
|
||||
/* and re-link enemy state now that he's spawned */
|
||||
if (enemy && enemy->inuse && enemy->deadflag != DEAD_DEAD)
|
||||
{
|
||||
self->enemy = enemy;
|
||||
}
|
||||
|
||||
if (oldenemy && oldenemy->inuse && oldenemy->deadflag != DEAD_DEAD)
|
||||
{
|
||||
self->oldenemy = oldenemy;
|
||||
}
|
||||
|
||||
if (!self->enemy)
|
||||
{
|
||||
self->enemy = self->oldenemy;
|
||||
self->oldenemy = NULL;
|
||||
}
|
||||
|
||||
enemy = self->enemy;
|
||||
|
||||
if (enemy)
|
||||
{
|
||||
FoundTarget(self);
|
||||
VectorCopy(self->pos1, self->monsterinfo.last_sighting);
|
||||
}
|
||||
|
||||
if (enemy && visible(self, enemy))
|
||||
{
|
||||
VectorSubtract(enemy->s.origin, self->s.origin, vec);
|
||||
self->s.angles[YAW] = vectoyaw(vec);
|
||||
VectorNormalize(vec);
|
||||
}
|
||||
else
|
||||
AngleVectors(self->s.angles, vec, NULL, NULL);
|
||||
|
||||
VectorScale(vec, 400, self->velocity);
|
||||
/* the jump frames are fixed length so best to normalize the up speed */
|
||||
self->velocity[2] = 200.0f * (sv_gravity->value / 800.0f);
|
||||
|
||||
self->groundentity = NULL;
|
||||
self->s.origin[2] += 1;
|
||||
gi.linkentity(self);
|
||||
|
||||
self->pain_debounce_time = level.time + 1;
|
||||
|
||||
self->monsterinfo.currentmove = &makron_move_sight;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1142,4 +1231,9 @@ MakronToss(edict_t *self)
|
|||
ent->think = MakronSpawn;
|
||||
ent->target = self->target;
|
||||
VectorCopy(self->s.origin, ent->s.origin);
|
||||
VectorCopy(self->s.angles, ent->s.angles);
|
||||
VectorCopy(self->monsterinfo.last_sighting, ent->pos1);
|
||||
|
||||
ent->enemy = self->enemy;
|
||||
ent->oldenemy = self->oldenemy;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Brain.
|
||||
*
|
||||
|
@ -23,9 +42,37 @@ static int sound_melee1;
|
|||
static int sound_melee2;
|
||||
static int sound_melee3;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
|
||||
void brain_run(edict_t *self);
|
||||
void brain_dead(edict_t *self);
|
||||
|
||||
void
|
||||
brain_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("brain/step1.wav");
|
||||
sound_step2 = gi.soundindex("brain/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
brain_sight(edict_t *self, edict_t *other /* unused */)
|
||||
{
|
||||
|
@ -49,7 +96,8 @@ brain_search(edict_t *self)
|
|||
}
|
||||
|
||||
/* STAND */
|
||||
mframe_t brain_frames_stand[] = {
|
||||
|
||||
static mframe_t brain_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -84,11 +132,12 @@ mframe_t brain_frames_stand[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_stand = {
|
||||
mmove_t brain_move_stand =
|
||||
{
|
||||
FRAME_stand01,
|
||||
FRAME_stand30,
|
||||
brain_frames_stand,
|
||||
NULL
|
||||
FRAME_stand30,
|
||||
brain_frames_stand,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -103,7 +152,8 @@ brain_stand(edict_t *self)
|
|||
}
|
||||
|
||||
/* IDLE */
|
||||
mframe_t brain_frames_idle[] = {
|
||||
|
||||
static mframe_t brain_frames_idle[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -138,11 +188,12 @@ mframe_t brain_frames_idle[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_idle = {
|
||||
mmove_t brain_move_idle =
|
||||
{
|
||||
FRAME_stand31,
|
||||
FRAME_stand60,
|
||||
brain_frames_idle,
|
||||
brain_stand
|
||||
FRAME_stand60,
|
||||
brain_frames_idle,
|
||||
brain_stand
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -158,25 +209,27 @@ brain_idle(edict_t *self)
|
|||
}
|
||||
|
||||
/* WALK */
|
||||
mframe_t brain_frames_walk1[] = {
|
||||
|
||||
static mframe_t brain_frames_walk1[] = {
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 3, brain_footstep},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, -4, NULL},
|
||||
{ai_walk, -1, NULL},
|
||||
{ai_walk, -1, brain_footstep},
|
||||
{ai_walk, 2, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_walk1 = {
|
||||
mmove_t brain_move_walk1 =
|
||||
{
|
||||
FRAME_walk101,
|
||||
FRAME_walk111,
|
||||
brain_frames_walk1,
|
||||
NULL
|
||||
brain_frames_walk1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -190,7 +243,7 @@ brain_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &brain_move_walk1;
|
||||
}
|
||||
|
||||
mframe_t brain_frames_defense[] = {
|
||||
static mframe_t brain_frames_defense[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -202,14 +255,15 @@ mframe_t brain_frames_defense[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_defense = {
|
||||
mmove_t brain_move_defense =
|
||||
{
|
||||
FRAME_defens01,
|
||||
FRAME_defens08,
|
||||
brain_frames_defense,
|
||||
NULL
|
||||
FRAME_defens08,
|
||||
brain_frames_defense,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t brain_frames_pain3[] = {
|
||||
static mframe_t brain_frames_pain3[] = {
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
|
@ -218,14 +272,15 @@ mframe_t brain_frames_pain3[] = {
|
|||
{ai_move, -4, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_pain3 = {
|
||||
mmove_t brain_move_pain3 =
|
||||
{
|
||||
FRAME_pain301,
|
||||
FRAME_pain306,
|
||||
brain_frames_pain3,
|
||||
brain_run
|
||||
FRAME_pain306,
|
||||
brain_frames_pain3,
|
||||
brain_run
|
||||
};
|
||||
|
||||
mframe_t brain_frames_pain2[] = {
|
||||
static mframe_t brain_frames_pain2[] = {
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -236,17 +291,18 @@ mframe_t brain_frames_pain2[] = {
|
|||
{ai_move, -2, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_pain2 = {
|
||||
mmove_t brain_move_pain2 =
|
||||
{
|
||||
FRAME_pain201,
|
||||
FRAME_pain208,
|
||||
brain_frames_pain2,
|
||||
brain_run
|
||||
};
|
||||
|
||||
mframe_t brain_frames_pain1[] = {
|
||||
static mframe_t brain_frames_pain1[] = {
|
||||
{ai_move, -6, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -6, NULL},
|
||||
{ai_move, -6, brain_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -263,36 +319,38 @@ mframe_t brain_frames_pain1[] = {
|
|||
{ai_move, 1, NULL},
|
||||
{ai_move, 7, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 3, brain_footstep},
|
||||
{ai_move, -1, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_pain1 = {
|
||||
mmove_t brain_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain121,
|
||||
brain_frames_pain1,
|
||||
brain_run
|
||||
FRAME_pain121,
|
||||
brain_frames_pain1,
|
||||
brain_run
|
||||
};
|
||||
|
||||
mframe_t brain_frames_duck[] = {
|
||||
static mframe_t brain_frames_duck[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -2, monster_duck_down},
|
||||
{ai_move, 17, monster_duck_hold},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -3, brain_footstep},
|
||||
{ai_move, -1, monster_duck_up},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -6, NULL},
|
||||
{ai_move, -6, NULL}
|
||||
{ai_move, -6, brain_footstep}
|
||||
};
|
||||
|
||||
mmove_t brain_move_duck = {
|
||||
mmove_t brain_move_duck =
|
||||
{
|
||||
FRAME_duck01,
|
||||
FRAME_duck08,
|
||||
brain_frames_duck,
|
||||
brain_run
|
||||
};
|
||||
|
||||
mframe_t brain_frames_death2[] = {
|
||||
static mframe_t brain_frames_death2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -300,14 +358,15 @@ mframe_t brain_frames_death2[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_death2 = {
|
||||
mmove_t brain_move_death2 =
|
||||
{
|
||||
FRAME_death201,
|
||||
FRAME_death205,
|
||||
brain_frames_death2,
|
||||
brain_dead
|
||||
brain_dead
|
||||
};
|
||||
|
||||
mframe_t brain_frames_death1[] = {
|
||||
static mframe_t brain_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
|
@ -328,7 +387,8 @@ mframe_t brain_frames_death1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_death1 = {
|
||||
mmove_t brain_move_death1 =
|
||||
{
|
||||
FRAME_death101,
|
||||
FRAME_death118,
|
||||
brain_frames_death1,
|
||||
|
@ -336,6 +396,7 @@ mmove_t brain_move_death1 = {
|
|||
};
|
||||
|
||||
/* MELEE */
|
||||
|
||||
void
|
||||
brain_swing_right(edict_t *self)
|
||||
{
|
||||
|
@ -379,13 +440,13 @@ brain_swing_left(edict_t *self)
|
|||
void
|
||||
brain_hit_left(edict_t *self)
|
||||
{
|
||||
vec3_t aim;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec3_t aim;
|
||||
|
||||
VectorSet(aim, MELEE_DISTANCE, self->mins[0], 8);
|
||||
|
||||
if (fire_hit(self, aim, (15 + (rand() % 5)), 40))
|
||||
|
@ -394,11 +455,11 @@ brain_hit_left(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t brain_frames_attack1[] = {
|
||||
static mframe_t brain_frames_attack1[] = {
|
||||
{ai_charge, 8, NULL},
|
||||
{ai_charge, 3, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, brain_footstep},
|
||||
{ai_charge, -3, brain_swing_right},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, -5, NULL},
|
||||
|
@ -412,14 +473,15 @@ mframe_t brain_frames_attack1[] = {
|
|||
{ai_charge, -1, NULL},
|
||||
{ai_charge, -3, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, -11, NULL}
|
||||
{ai_charge, -11, brain_footstep}
|
||||
};
|
||||
|
||||
mmove_t brain_move_attack1 = {
|
||||
mmove_t brain_move_attack1 =
|
||||
{
|
||||
FRAME_attak101,
|
||||
FRAME_attak118,
|
||||
brain_frames_attack1,
|
||||
brain_run
|
||||
FRAME_attak118,
|
||||
brain_frames_attack1,
|
||||
brain_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -472,7 +534,7 @@ brain_chest_closed(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t brain_frames_attack2[] = {
|
||||
static mframe_t brain_frames_attack2[] = {
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, -4, NULL},
|
||||
{ai_charge, -4, NULL},
|
||||
|
@ -492,11 +554,12 @@ mframe_t brain_frames_attack2[] = {
|
|||
{ai_charge, -6, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_attack2 = {
|
||||
mmove_t brain_move_attack2 =
|
||||
{
|
||||
FRAME_attak201,
|
||||
FRAME_attak217,
|
||||
brain_frames_attack2,
|
||||
brain_run
|
||||
FRAME_attak217,
|
||||
brain_frames_attack2,
|
||||
brain_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -518,23 +581,25 @@ brain_melee(edict_t *self)
|
|||
}
|
||||
|
||||
/* RUN */
|
||||
mframe_t brain_frames_run[] = {
|
||||
|
||||
static mframe_t brain_frames_run[] = {
|
||||
{ai_run, 9, NULL},
|
||||
{ai_run, 2, NULL},
|
||||
{ai_run, 3, NULL},
|
||||
{ai_run, 3, NULL},
|
||||
{ai_run, 3, brain_footstep},
|
||||
{ai_run, 1, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, -4, NULL},
|
||||
{ai_run, -1, NULL},
|
||||
{ai_run, -1, brain_footstep},
|
||||
{ai_run, 2, NULL}
|
||||
};
|
||||
|
||||
mmove_t brain_move_run = {
|
||||
mmove_t brain_move_run =
|
||||
{
|
||||
FRAME_walk101,
|
||||
FRAME_walk111,
|
||||
FRAME_walk111,
|
||||
brain_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
@ -560,8 +625,8 @@ brain_run(edict_t *self)
|
|||
}
|
||||
|
||||
void
|
||||
brain_pain(edict_t *self, edict_t *other /* unused */, float kick /* unused */,
|
||||
int damage /* unused */)
|
||||
brain_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage /* unused */)
|
||||
{
|
||||
float r;
|
||||
|
||||
|
@ -645,19 +710,23 @@ brain_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -725,6 +794,11 @@ SP_monster_brain(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
sound_chest_open = gi.soundindex("brain/brnatck1.wav");
|
||||
sound_tentacles_extend = gi.soundindex("brain/brnatck2.wav");
|
||||
sound_tentacles_retract = gi.soundindex("brain/brnatck3.wav");
|
||||
|
|
|
@ -634,7 +634,7 @@ carrier_start_spawn(edict_t *self)
|
|||
CarrierMachineGun(self);
|
||||
}
|
||||
|
||||
mframe_t carrier_frames_stand[] = {
|
||||
static mframe_t carrier_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -657,7 +657,7 @@ mmove_t carrier_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_walk[] = {
|
||||
static mframe_t carrier_frames_walk[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
|
@ -680,7 +680,7 @@ mmove_t carrier_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_run[] = {
|
||||
static mframe_t carrier_frames_run[] = {
|
||||
{ai_run, 6, CarrierCoopCheck},
|
||||
{ai_run, 6, CarrierCoopCheck},
|
||||
{ai_run, 6, CarrierCoopCheck},
|
||||
|
@ -703,7 +703,7 @@ mmove_t carrier_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_pre_mg[] = {
|
||||
static mframe_t carrier_frames_attack_pre_mg[] = {
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
|
@ -722,7 +722,7 @@ mmove_t carrier_move_attack_pre_mg = {
|
|||
};
|
||||
|
||||
/* Loop this */
|
||||
mframe_t carrier_frames_attack_mg[] = {
|
||||
static mframe_t carrier_frames_attack_mg[] = {
|
||||
{ai_charge, -2, CarrierMachineGun},
|
||||
{ai_charge, -2, CarrierMachineGun},
|
||||
{ai_charge, -2, carrier_reattack_mg}
|
||||
|
@ -735,7 +735,7 @@ mmove_t carrier_move_attack_mg = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_post_mg[] = {
|
||||
static mframe_t carrier_frames_attack_post_mg[] = {
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
|
@ -749,7 +749,7 @@ mmove_t carrier_move_attack_post_mg = {
|
|||
carrier_run
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_pre_gren[] = {
|
||||
static mframe_t carrier_frames_attack_pre_gren[] = {
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
|
@ -765,7 +765,7 @@ mmove_t carrier_move_attack_pre_gren = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_gren[] = {
|
||||
static mframe_t carrier_frames_attack_gren[] = {
|
||||
{ai_charge, -15, CarrierGrenade},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
|
@ -779,7 +779,7 @@ mmove_t carrier_move_attack_gren = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_post_gren[] = {
|
||||
static mframe_t carrier_frames_attack_post_gren[] = {
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
{ai_charge, 4, CarrierCoopCheck},
|
||||
|
@ -795,7 +795,7 @@ mmove_t carrier_move_attack_post_gren = {
|
|||
carrier_run
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_attack_rocket[] = {
|
||||
static mframe_t carrier_frames_attack_rocket[] = {
|
||||
{ai_charge, 15, CarrierRocket}
|
||||
};
|
||||
|
||||
|
@ -844,7 +844,7 @@ CarrierSaveLoc(edict_t *self)
|
|||
self->pos1[2] += self->enemy->viewheight;
|
||||
}
|
||||
|
||||
mframe_t carrier_frames_attack_rail[] = {
|
||||
static mframe_t carrier_frames_attack_rail[] = {
|
||||
{ai_charge, 2, CarrierCoopCheck},
|
||||
{ai_charge, 2, CarrierSaveLoc},
|
||||
{ai_charge, 2, CarrierCoopCheck},
|
||||
|
@ -863,7 +863,7 @@ mmove_t carrier_move_attack_rail = {
|
|||
carrier_run
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_spawn[] = {
|
||||
static mframe_t carrier_frames_spawn[] = {
|
||||
{ai_charge, -2, CarrierMachineGun},
|
||||
{ai_charge, -2, CarrierMachineGun},
|
||||
{ai_charge, -2, CarrierMachineGun},
|
||||
|
@ -891,7 +891,7 @@ mmove_t carrier_move_spawn = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_pain_heavy[] = {
|
||||
static mframe_t carrier_frames_pain_heavy[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -911,7 +911,7 @@ mmove_t carrier_move_pain_heavy = {
|
|||
carrier_run
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_pain_light[] = {
|
||||
static mframe_t carrier_frames_pain_light[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -925,7 +925,7 @@ mmove_t carrier_move_pain_light = {
|
|||
carrier_run
|
||||
};
|
||||
|
||||
mframe_t carrier_frames_death[] = {
|
||||
static mframe_t carrier_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Iron Maiden.
|
||||
*
|
||||
|
@ -34,6 +53,34 @@ static int sound_pain3;
|
|||
static int sound_sight;
|
||||
static int sound_search;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
|
||||
void
|
||||
chick_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("bitch/step1.wav");
|
||||
sound_step2 = gi.soundindex("bitch/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChickMoan(edict_t *self)
|
||||
{
|
||||
|
@ -52,7 +99,7 @@ ChickMoan(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t chick_frames_fidget[] = {
|
||||
static mframe_t chick_frames_fidget[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -85,7 +132,8 @@ mframe_t chick_frames_fidget[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_fidget = {
|
||||
mmove_t chick_move_fidget =
|
||||
{
|
||||
FRAME_stand201,
|
||||
FRAME_stand230,
|
||||
chick_frames_fidget,
|
||||
|
@ -111,7 +159,7 @@ chick_fidget(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t chick_frames_stand[] = {
|
||||
static mframe_t chick_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -144,7 +192,8 @@ mframe_t chick_frames_stand[] = {
|
|||
{ai_stand, 0, chick_fidget},
|
||||
};
|
||||
|
||||
mmove_t chick_move_stand = {
|
||||
mmove_t chick_move_stand =
|
||||
{
|
||||
FRAME_stand101,
|
||||
FRAME_stand130,
|
||||
chick_frames_stand,
|
||||
|
@ -162,7 +211,7 @@ chick_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &chick_move_stand;
|
||||
}
|
||||
|
||||
mframe_t chick_frames_start_run[] = {
|
||||
static mframe_t chick_frames_start_run[] = {
|
||||
{ai_run, 1, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
|
@ -175,47 +224,50 @@ mframe_t chick_frames_start_run[] = {
|
|||
{ai_run, 3, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_start_run = {
|
||||
mmove_t chick_move_start_run =
|
||||
{
|
||||
FRAME_walk01,
|
||||
FRAME_walk10,
|
||||
chick_frames_start_run,
|
||||
chick_run
|
||||
};
|
||||
|
||||
mframe_t chick_frames_run[] = {
|
||||
static mframe_t chick_frames_run[] = {
|
||||
{ai_run, 6, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, chick_footstep},
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 5, NULL},
|
||||
{ai_run, 7, NULL},
|
||||
{ai_run, 4, NULL},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 11, chick_footstep},
|
||||
{ai_run, 5, NULL},
|
||||
{ai_run, 9, NULL},
|
||||
{ai_run, 7, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_run = {
|
||||
mmove_t chick_move_run =
|
||||
{
|
||||
FRAME_walk11,
|
||||
FRAME_walk20,
|
||||
chick_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t chick_frames_walk[] = {
|
||||
static mframe_t chick_frames_walk[] = {
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
{ai_walk, 8, chick_footstep},
|
||||
{ai_walk, 13, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 11, NULL},
|
||||
{ai_walk, 11, chick_footstep},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, 7, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_walk = {
|
||||
mmove_t chick_move_walk =
|
||||
{
|
||||
FRAME_walk11,
|
||||
FRAME_walk20,
|
||||
chick_frames_walk,
|
||||
|
@ -260,7 +312,7 @@ chick_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t chick_frames_pain1[] = {
|
||||
static mframe_t chick_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -268,28 +320,31 @@ mframe_t chick_frames_pain1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_pain1 = {
|
||||
mmove_t chick_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain105,
|
||||
chick_frames_pain1, chick_run
|
||||
};
|
||||
|
||||
mframe_t chick_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_pain2 = {
|
||||
FRAME_pain201,
|
||||
FRAME_pain205,
|
||||
chick_frames_pain2,
|
||||
chick_frames_pain1,
|
||||
chick_run
|
||||
};
|
||||
|
||||
mframe_t chick_frames_pain3[] = {
|
||||
static mframe_t chick_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_pain2 =
|
||||
{
|
||||
FRAME_pain201,
|
||||
FRAME_pain205,
|
||||
chick_frames_pain2,
|
||||
chick_run
|
||||
};
|
||||
|
||||
static mframe_t chick_frames_pain3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -6, NULL},
|
||||
|
@ -313,15 +368,17 @@ mframe_t chick_frames_pain3[] = {
|
|||
{ai_move, 2, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_pain3 = {
|
||||
mmove_t chick_move_pain3 =
|
||||
{
|
||||
FRAME_pain301,
|
||||
FRAME_pain321,
|
||||
chick_frames_pain3,
|
||||
chick_frames_pain3,
|
||||
chick_run
|
||||
};
|
||||
|
||||
void
|
||||
chick_pain(edict_t *self, edict_t *other /* other */, float kick /* other */, int damage)
|
||||
chick_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
float r;
|
||||
|
||||
|
@ -403,24 +460,24 @@ chick_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t chick_frames_death2[] = {
|
||||
static mframe_t chick_frames_death2[] = {
|
||||
{ai_move, -6, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, chick_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 10, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 3, chick_footstep},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, chick_footstep},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, 4, NULL},
|
||||
|
@ -429,14 +486,15 @@ mframe_t chick_frames_death2[] = {
|
|||
{ai_move, 1, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_death2 = {
|
||||
mmove_t chick_move_death2 =
|
||||
{
|
||||
FRAME_death201,
|
||||
FRAME_death223,
|
||||
chick_frames_death2,
|
||||
chick_dead
|
||||
};
|
||||
|
||||
mframe_t chick_frames_death1[] = {
|
||||
static mframe_t chick_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -7, NULL},
|
||||
|
@ -451,16 +509,18 @@ mframe_t chick_frames_death1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t chick_move_death1 = {
|
||||
mmove_t chick_move_death1 =
|
||||
{
|
||||
FRAME_death101,
|
||||
FRAME_death112,
|
||||
chick_frames_death1,
|
||||
chick_dead
|
||||
FRAME_death112,
|
||||
chick_frames_death1,
|
||||
chick_dead
|
||||
};
|
||||
|
||||
void
|
||||
chick_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
chick_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /*unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -472,20 +532,23 @@ chick_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage,
|
||||
GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -513,7 +576,7 @@ chick_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t chick_frames_duck[] = {
|
||||
static mframe_t chick_frames_duck[] = {
|
||||
{ai_move, 0, monster_duck_down},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 4, monster_duck_hold},
|
||||
|
@ -625,58 +688,26 @@ ChickRocket(edict_t *self)
|
|||
|
||||
VectorNormalize(dir);
|
||||
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (blindfire)
|
||||
{
|
||||
/* blindfire has different fail criteria for the trace */
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
if (!blind_rocket_ok(self, start, right, target, 10.0f, dir))
|
||||
{
|
||||
monster_fire_rocket(self, start, dir, 50,
|
||||
rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(target, vec);
|
||||
VectorMA(vec, -10, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec,
|
||||
self, MASK_SHOT);
|
||||
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
{
|
||||
monster_fire_rocket(self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ok, that failed. try to the right */
|
||||
VectorCopy(target, vec);
|
||||
VectorMA(vec, 10, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec,
|
||||
self, MASK_SHOT);
|
||||
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
{
|
||||
monster_fire_rocket(self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if ((trace.ent == self->enemy) || (trace.ent == world))
|
||||
if (((trace.ent != self->enemy) && (trace.ent != world)) ||
|
||||
((trace.fraction <= 0.5f) && !trace.ent->client))
|
||||
{
|
||||
if ((trace.fraction > 0.5) || (trace.ent && trace.ent->client))
|
||||
{
|
||||
monster_fire_rocket(self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
monster_fire_rocket(self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -701,7 +732,7 @@ ChickReload(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t chick_frames_start_attack1[] = {
|
||||
static mframe_t chick_frames_start_attack1[] = {
|
||||
{ai_charge, 0, Chick_PreAttack1},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -710,57 +741,60 @@ mframe_t chick_frames_start_attack1[] = {
|
|||
{ai_charge, -3, NULL},
|
||||
{ai_charge, 3, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, 7, NULL},
|
||||
{ai_charge, 7, chick_footstep},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, chick_attack1}
|
||||
};
|
||||
|
||||
mmove_t chick_move_start_attack1 = {
|
||||
mmove_t chick_move_start_attack1 =
|
||||
{
|
||||
FRAME_attak101,
|
||||
FRAME_attak113,
|
||||
chick_frames_start_attack1,
|
||||
NULL
|
||||
FRAME_attak113,
|
||||
chick_frames_start_attack1,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t chick_frames_attack1[] = {
|
||||
static mframe_t chick_frames_attack1[] = {
|
||||
{ai_charge, 19, ChickRocket},
|
||||
{ai_charge, -6, NULL},
|
||||
{ai_charge, -5, NULL},
|
||||
{ai_charge, -5, chick_footstep},
|
||||
{ai_charge, -2, NULL},
|
||||
{ai_charge, -7, NULL},
|
||||
{ai_charge, -7, chick_footstep},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 10, ChickReload},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, 5, chick_footstep},
|
||||
{ai_charge, 6, NULL},
|
||||
{ai_charge, 6, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 4, chick_footstep},
|
||||
{ai_charge, 3, chick_rerocket}
|
||||
};
|
||||
|
||||
mmove_t chick_move_attack1 = {
|
||||
mmove_t chick_move_attack1 =
|
||||
{
|
||||
FRAME_attak114,
|
||||
FRAME_attak127,
|
||||
chick_frames_attack1,
|
||||
NULL
|
||||
FRAME_attak127,
|
||||
chick_frames_attack1,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t chick_frames_end_attack1[] = {
|
||||
static mframe_t chick_frames_end_attack1[] = {
|
||||
{ai_charge, -3, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, -6, NULL},
|
||||
{ai_charge, -4, NULL},
|
||||
{ai_charge, -2, NULL}
|
||||
{ai_charge, -2, chick_footstep}
|
||||
};
|
||||
|
||||
mmove_t chick_move_end_attack1 = {
|
||||
mmove_t chick_move_end_attack1 =
|
||||
{
|
||||
FRAME_attak128,
|
||||
FRAME_attak132,
|
||||
chick_frames_end_attack1,
|
||||
chick_run
|
||||
chick_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -807,7 +841,7 @@ chick_attack1(edict_t *self)
|
|||
self->monsterinfo.currentmove = &chick_move_attack1;
|
||||
}
|
||||
|
||||
mframe_t chick_frames_slash[] = {
|
||||
static mframe_t chick_frames_slash[] = {
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 7, ChickSlash},
|
||||
{ai_charge, -7, NULL},
|
||||
|
@ -819,24 +853,26 @@ mframe_t chick_frames_slash[] = {
|
|||
{ai_charge, -2, chick_reslash}
|
||||
};
|
||||
|
||||
mmove_t chick_move_slash = {
|
||||
mmove_t chick_move_slash =
|
||||
{
|
||||
FRAME_attak204,
|
||||
FRAME_attak212,
|
||||
chick_frames_slash,
|
||||
NULL
|
||||
FRAME_attak212,
|
||||
chick_frames_slash,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t chick_frames_end_slash[] = {
|
||||
static mframe_t chick_frames_end_slash[] = {
|
||||
{ai_charge, -6, NULL},
|
||||
{ai_charge, -1, NULL},
|
||||
{ai_charge, -6, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
{ai_charge, 0, chick_footstep}
|
||||
};
|
||||
|
||||
mmove_t chick_move_end_slash = {
|
||||
mmove_t chick_move_end_slash =
|
||||
{
|
||||
FRAME_attak213,
|
||||
FRAME_attak216,
|
||||
chick_frames_end_slash,
|
||||
chick_frames_end_slash,
|
||||
chick_run
|
||||
};
|
||||
|
||||
|
@ -879,17 +915,18 @@ chick_slash(edict_t *self)
|
|||
self->monsterinfo.currentmove = &chick_move_slash;
|
||||
}
|
||||
|
||||
mframe_t chick_frames_start_slash[] = {
|
||||
static mframe_t chick_frames_start_slash[] = {
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 8, NULL},
|
||||
{ai_charge, 3, NULL}
|
||||
{ai_charge, 3, chick_footstep}
|
||||
};
|
||||
|
||||
mmove_t chick_move_start_slash = {
|
||||
mmove_t chick_move_start_slash =
|
||||
{
|
||||
FRAME_attak201,
|
||||
FRAME_attak203,
|
||||
chick_frames_start_slash,
|
||||
chick_slash
|
||||
chick_slash
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1064,6 +1101,11 @@ SP_monster_chick(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
sound_missile_prelaunch = gi.soundindex("chick/chkatck1.wav");
|
||||
sound_missile_launch = gi.soundindex("chick/chkatck2.wav");
|
||||
sound_melee_swing = gi.soundindex("chick/chkatck3.wav");
|
||||
|
|
|
@ -21,7 +21,7 @@ static int sound_sight;
|
|||
|
||||
void flipper_stand(edict_t *self);
|
||||
|
||||
mframe_t flipper_frames_stand[] = {
|
||||
static mframe_t flipper_frames_stand[] = {
|
||||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,7 @@ flipper_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &flipper_move_stand;
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_run[] = {
|
||||
static mframe_t flipper_frames_run[] = {
|
||||
{ai_run, FLIPPER_RUN_SPEED, NULL}, /* 6 */
|
||||
{ai_run, FLIPPER_RUN_SPEED, NULL},
|
||||
{ai_run, FLIPPER_RUN_SPEED, NULL},
|
||||
|
@ -90,7 +90,7 @@ flipper_run_loop(edict_t *self)
|
|||
self->monsterinfo.currentmove = &flipper_move_run_loop;
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_run_start[] = {
|
||||
static mframe_t flipper_frames_run_start[] = {
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
|
@ -118,7 +118,7 @@ flipper_run(edict_t *self)
|
|||
}
|
||||
|
||||
/* Standard Swimming */
|
||||
mframe_t flipper_frames_walk[] = {
|
||||
static mframe_t flipper_frames_walk[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
|
@ -163,7 +163,7 @@ flipper_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &flipper_move_walk;
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_start_run[] = {
|
||||
static mframe_t flipper_frames_start_run[] = {
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
|
@ -189,7 +189,7 @@ flipper_start_run(edict_t *self)
|
|||
self->monsterinfo.currentmove = &flipper_move_start_run;
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_pain2[] = {
|
||||
static mframe_t flipper_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -204,7 +204,7 @@ mmove_t flipper_move_pain2 = {
|
|||
flipper_run
|
||||
};
|
||||
|
||||
mframe_t flipper_frames_pain1[] = {
|
||||
static mframe_t flipper_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -244,7 +244,7 @@ flipper_preattack(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_attack[] = {
|
||||
static mframe_t flipper_frames_attack[] = {
|
||||
{ai_charge, 0, flipper_preattack},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -329,20 +329,31 @@ flipper_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
void
|
||||
flipper_dead(edict_t *self)
|
||||
{
|
||||
vec3_t p;
|
||||
trace_t tr;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSet(self->mins, -16, -16, -24);
|
||||
VectorSet(self->maxs, 16, 16, -8);
|
||||
/* original dead bbox was wrong - and make sure the bbox adjustment stays in solidity */
|
||||
|
||||
p[0] = self->s.origin[0];
|
||||
p[1] = self->s.origin[1];
|
||||
p[2] = self->s.origin[2] - 8;
|
||||
|
||||
tr = gi.trace(self->s.origin, self->mins, self->maxs, p, self, self->clipmask);
|
||||
|
||||
self->mins[2] = tr.endpos[2] - self->s.origin[2];
|
||||
|
||||
self->movetype = MOVETYPE_TOSS;
|
||||
self->svflags |= SVF_DEADMONSTER;
|
||||
self->nextthink = 0;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t flipper_frames_death[] = {
|
||||
static mframe_t flipper_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -79,7 +79,7 @@ floater_fire_blaster(edict_t *self)
|
|||
monster_fire_blaster(self, start, dir, 1, 1000, MZ2_FLOAT_BLASTER_1, effect);
|
||||
}
|
||||
|
||||
mframe_t floater_frames_stand1[] = {
|
||||
static mframe_t floater_frames_stand1[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -141,7 +141,7 @@ mmove_t floater_move_stand1 = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t floater_frames_stand2[] = {
|
||||
static mframe_t floater_frames_stand2[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -221,7 +221,7 @@ floater_stand(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t floater_frames_activate[] = {
|
||||
static mframe_t floater_frames_activate[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -261,7 +261,7 @@ mmove_t floater_move_activate = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t floater_frames_attack1[] = {
|
||||
static mframe_t floater_frames_attack1[] = {
|
||||
{ai_charge, 0, NULL}, /* Blaster attack */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -286,7 +286,7 @@ mmove_t floater_move_attack1 = {
|
|||
};
|
||||
|
||||
/* circle strafe frames */
|
||||
mframe_t floater_frames_attack1a[] = {
|
||||
static mframe_t floater_frames_attack1a[] = {
|
||||
{ai_charge, 10, NULL}, // Blaster attack
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
|
@ -310,7 +310,7 @@ mmove_t floater_move_attack1a = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_attack2[] = {
|
||||
static mframe_t floater_frames_attack2[] = {
|
||||
{ai_charge, 0, NULL}, /* Claws */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -345,7 +345,7 @@ mmove_t floater_move_attack2 = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_attack3[] = {
|
||||
static mframe_t floater_frames_attack3[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -389,7 +389,7 @@ mmove_t floater_move_attack3 = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_death[] = {
|
||||
static mframe_t floater_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -412,7 +412,7 @@ mmove_t floater_move_death = {
|
|||
floater_dead
|
||||
};
|
||||
|
||||
mframe_t floater_frames_pain1[] = {
|
||||
static mframe_t floater_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -429,7 +429,7 @@ mmove_t floater_move_pain1 = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_pain2[] = {
|
||||
static mframe_t floater_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -447,7 +447,7 @@ mmove_t floater_move_pain2 = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_pain3[] = {
|
||||
static mframe_t floater_frames_pain3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -469,7 +469,7 @@ mmove_t floater_move_pain3 = {
|
|||
floater_run
|
||||
};
|
||||
|
||||
mframe_t floater_frames_walk[] = {
|
||||
static mframe_t floater_frames_walk[] = {
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
|
@ -531,7 +531,7 @@ mmove_t floater_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t floater_frames_run[] = {
|
||||
static mframe_t floater_frames_run[] = {
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 13, NULL},
|
||||
|
|
|
@ -65,7 +65,7 @@ flyer_pop_blades(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t flyer_frames_stand[] = {
|
||||
static mframe_t flyer_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -120,7 +120,7 @@ mmove_t flyer_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_walk[] = {
|
||||
static mframe_t flyer_frames_walk[] = {
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
|
@ -175,7 +175,7 @@ mmove_t flyer_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_run[] = {
|
||||
static mframe_t flyer_frames_run[] = {
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
|
@ -230,7 +230,7 @@ mmove_t flyer_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_kamizake[] = {
|
||||
static mframe_t flyer_frames_kamizake[] = {
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
|
@ -373,7 +373,7 @@ flyer_kamikaze_check(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t flyer_frames_start[] = {
|
||||
static mframe_t flyer_frames_start[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -389,7 +389,7 @@ mmove_t flyer_move_start = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_stop[] = {
|
||||
static mframe_t flyer_frames_stop[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -428,7 +428,7 @@ flyer_start(edict_t *self)
|
|||
self->monsterinfo.currentmove = &flyer_move_start;
|
||||
}
|
||||
|
||||
mframe_t flyer_frames_rollright[] = {
|
||||
static mframe_t flyer_frames_rollright[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -447,7 +447,7 @@ mmove_t flyer_move_rollright = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_rollleft[] = {
|
||||
static mframe_t flyer_frames_rollleft[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -466,7 +466,7 @@ mmove_t flyer_move_rollleft = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_pain3[] = {
|
||||
static mframe_t flyer_frames_pain3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -480,7 +480,7 @@ mmove_t flyer_move_pain3 = {
|
|||
flyer_run
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_pain2[] = {
|
||||
static mframe_t flyer_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -494,7 +494,7 @@ mmove_t flyer_move_pain2 = {
|
|||
flyer_run
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_pain1[] = {
|
||||
static mframe_t flyer_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -513,7 +513,7 @@ mmove_t flyer_move_pain1 = {
|
|||
flyer_run
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_defense[] = {
|
||||
static mframe_t flyer_frames_defense[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* Hold this frame */
|
||||
|
@ -529,7 +529,7 @@ mmove_t flyer_move_defense = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_bankright[] = {
|
||||
static mframe_t flyer_frames_bankright[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -546,7 +546,7 @@ mmove_t flyer_move_bankright = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_bankleft[] = {
|
||||
static mframe_t flyer_frames_bankleft[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -626,7 +626,7 @@ flyer_fireright(edict_t *self)
|
|||
flyer_fire(self, MZ2_FLYER_BLASTER_2);
|
||||
}
|
||||
|
||||
mframe_t flyer_frames_attack2[] = {
|
||||
static mframe_t flyer_frames_attack2[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -654,7 +654,7 @@ mmove_t flyer_move_attack2 = {
|
|||
};
|
||||
|
||||
/* circle strafe frames */
|
||||
mframe_t flyer_frames_attack3[] = {
|
||||
static mframe_t flyer_frames_attack3[] = {
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
|
@ -711,7 +711,7 @@ flyer_slash_right(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t flyer_frames_start_melee[] = {
|
||||
static mframe_t flyer_frames_start_melee[] = {
|
||||
{ai_charge, 0, flyer_pop_blades},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -727,7 +727,7 @@ mmove_t flyer_move_start_melee = {
|
|||
flyer_loop_melee
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_end_melee[] = {
|
||||
static mframe_t flyer_frames_end_melee[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
|
@ -740,7 +740,7 @@ mmove_t flyer_move_end_melee = {
|
|||
flyer_run
|
||||
};
|
||||
|
||||
mframe_t flyer_frames_loop_melee[] = {
|
||||
static mframe_t flyer_frames_loop_melee[] = {
|
||||
{ai_charge, 0, NULL}, /* Loop Start */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, flyer_slash_left}, /* Left Wing Strike */
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Gladiator.
|
||||
*
|
||||
|
@ -19,6 +38,33 @@ static int sound_idle;
|
|||
static int sound_search;
|
||||
static int sound_sight;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
void
|
||||
gladiator_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("gladiator/step1.wav");
|
||||
sound_step2 = gi.soundindex("gladiator/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gladiator_idle(edict_t *self)
|
||||
{
|
||||
|
@ -63,7 +109,7 @@ gladiator_cleaver_swing(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_stand[] = {
|
||||
static mframe_t gladiator_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -73,11 +119,12 @@ mframe_t gladiator_frames_stand[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_stand = {
|
||||
mmove_t gladiator_move_stand =
|
||||
{
|
||||
FRAME_stand1,
|
||||
FRAME_stand7,
|
||||
gladiator_frames_stand,
|
||||
NULL
|
||||
FRAME_stand7,
|
||||
gladiator_frames_stand,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -91,12 +138,12 @@ gladiator_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gladiator_move_stand;
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_walk[] = {
|
||||
static mframe_t gladiator_frames_walk[] = {
|
||||
{ai_walk, 15, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 2, gladiator_footstep},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
|
@ -104,17 +151,18 @@ mframe_t gladiator_frames_walk[] = {
|
|||
{ai_walk, 8, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 2, gladiator_footstep},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 8, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_walk = {
|
||||
mmove_t gladiator_move_walk =
|
||||
{
|
||||
FRAME_walk1,
|
||||
FRAME_walk16,
|
||||
gladiator_frames_walk,
|
||||
NULL
|
||||
FRAME_walk16,
|
||||
gladiator_frames_walk,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -128,20 +176,21 @@ gladiator_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gladiator_move_walk;
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_run[] = {
|
||||
static mframe_t gladiator_frames_run[] = {
|
||||
{ai_run, 23, NULL},
|
||||
{ai_run, 14, NULL},
|
||||
{ai_run, 14, NULL},
|
||||
{ai_run, 14, gladiator_footstep},
|
||||
{ai_run, 21, NULL},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 13, NULL}
|
||||
{ai_run, 13, gladiator_footstep}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_run = {
|
||||
mmove_t gladiator_move_run =
|
||||
{
|
||||
FRAME_run1,
|
||||
FRAME_run6,
|
||||
gladiator_frames_run,
|
||||
NULL
|
||||
FRAME_run6,
|
||||
gladiator_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -184,7 +233,7 @@ GaldiatorMelee(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_attack_melee[] = {
|
||||
static mframe_t gladiator_frames_attack_melee[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -204,11 +253,12 @@ mframe_t gladiator_frames_attack_melee[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_attack_melee = {
|
||||
mmove_t gladiator_move_attack_melee =
|
||||
{
|
||||
FRAME_melee1,
|
||||
FRAME_melee17,
|
||||
gladiator_frames_attack_melee,
|
||||
gladiator_run
|
||||
FRAME_melee17,
|
||||
gladiator_frames_attack_melee,
|
||||
gladiator_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -245,7 +295,7 @@ GladiatorGun(edict_t *self)
|
|||
monster_fire_railgun(self, start, dir, 50, 100, MZ2_GLADIATOR_RAILGUN_1);
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_attack_gun[] = {
|
||||
static mframe_t gladiator_frames_attack_gun[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -257,11 +307,12 @@ mframe_t gladiator_frames_attack_gun[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_attack_gun = {
|
||||
mmove_t gladiator_move_attack_gun =
|
||||
{
|
||||
FRAME_attack1,
|
||||
FRAME_attack9,
|
||||
gladiator_frames_attack_gun,
|
||||
gladiator_run
|
||||
FRAME_attack9,
|
||||
gladiator_frames_attack_gun,
|
||||
gladiator_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -275,13 +326,19 @@ gladiator_attack(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
/* a small safe zone */
|
||||
VectorSubtract(self->s.origin, self->enemy->s.origin, v);
|
||||
range = VectorLength(v);
|
||||
|
||||
if (range <= (MELEE_DISTANCE + 32))
|
||||
/* a small safe zone
|
||||
but not for stand-ground ones since players can
|
||||
abuse it by standing still inside this range
|
||||
*/
|
||||
if (!(self->monsterinfo.aiflags & AI_STAND_GROUND))
|
||||
{
|
||||
return;
|
||||
VectorSubtract(self->s.origin, self->enemy->s.origin, v);
|
||||
range = VectorLength(v);
|
||||
|
||||
if (range <= (MELEE_DISTANCE + 32))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* charge up the railgun */
|
||||
|
@ -291,7 +348,7 @@ gladiator_attack(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gladiator_move_attack_gun;
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_pain[] = {
|
||||
static mframe_t gladiator_frames_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -300,14 +357,15 @@ mframe_t gladiator_frames_pain[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_pain = {
|
||||
mmove_t gladiator_move_pain =
|
||||
{
|
||||
FRAME_pain1,
|
||||
FRAME_pain6,
|
||||
gladiator_frames_pain,
|
||||
gladiator_run
|
||||
FRAME_pain6,
|
||||
gladiator_frames_pain,
|
||||
gladiator_run
|
||||
};
|
||||
|
||||
mframe_t gladiator_frames_pain_air[] = {
|
||||
static mframe_t gladiator_frames_pain_air[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -317,15 +375,17 @@ mframe_t gladiator_frames_pain_air[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_pain_air = {
|
||||
mmove_t gladiator_move_pain_air =
|
||||
{
|
||||
FRAME_painup1,
|
||||
FRAME_painup7,
|
||||
gladiator_frames_pain_air,
|
||||
gladiator_run
|
||||
FRAME_painup7,
|
||||
gladiator_frames_pain_air,
|
||||
gladiator_run
|
||||
};
|
||||
|
||||
void
|
||||
gladiator_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
gladiator_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -390,7 +450,7 @@ gladiator_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t gladiator_frames_death[] = {
|
||||
static mframe_t gladiator_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -415,16 +475,18 @@ mframe_t gladiator_frames_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gladiator_move_death = {
|
||||
mmove_t gladiator_move_death =
|
||||
{
|
||||
FRAME_death1,
|
||||
FRAME_death22,
|
||||
gladiator_frames_death,
|
||||
gladiator_dead
|
||||
FRAME_death22,
|
||||
gladiator_frames_death,
|
||||
gladiator_dead
|
||||
};
|
||||
|
||||
void
|
||||
gladiator_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
gladiator_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage /*unused */,
|
||||
vec3_t point)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -436,19 +498,23 @@ gladiator_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(
|
||||
"misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -499,6 +565,11 @@ SP_monster_gladiator(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
sound_pain1 = gi.soundindex("gladiator/pain.wav");
|
||||
sound_pain2 = gi.soundindex("gladiator/gldpain2.wav");
|
||||
sound_die = gi.soundindex("gladiator/glddeth2.wav");
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Gunner.
|
||||
*
|
||||
|
@ -16,6 +35,9 @@ static int sound_open;
|
|||
static int sound_search;
|
||||
static int sound_sight;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
qboolean visible(edict_t *self, edict_t *other);
|
||||
void GunnerGrenade(edict_t *self);
|
||||
void GunnerFire(edict_t *self);
|
||||
|
@ -24,6 +46,30 @@ void gunner_refire_chain(edict_t *self);
|
|||
|
||||
void gunner_stand(edict_t *self);
|
||||
|
||||
void
|
||||
gunner_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("gunner/step1.wav");
|
||||
sound_step2 = gi.soundindex("gunner/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gunner_idlesound(edict_t *self)
|
||||
{
|
||||
|
@ -57,7 +103,7 @@ gunner_search(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_fidget[] = {
|
||||
static mframe_t gunner_frames_fidget[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -113,10 +159,11 @@ mframe_t gunner_frames_fidget[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_fidget = {
|
||||
mmove_t gunner_move_fidget =
|
||||
{
|
||||
FRAME_stand31,
|
||||
FRAME_stand70,
|
||||
gunner_frames_fidget,
|
||||
gunner_frames_fidget,
|
||||
gunner_stand
|
||||
};
|
||||
|
||||
|
@ -128,6 +175,11 @@ gunner_fidget(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->enemy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
|
||||
{
|
||||
return;
|
||||
|
@ -139,7 +191,7 @@ gunner_fidget(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_stand[] = {
|
||||
static mframe_t gunner_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -174,11 +226,12 @@ mframe_t gunner_frames_stand[] = {
|
|||
{ai_stand, 0, gunner_fidget}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_stand = {
|
||||
mmove_t gunner_move_stand =
|
||||
{
|
||||
FRAME_stand01,
|
||||
FRAME_stand30,
|
||||
gunner_frames_stand,
|
||||
NULL
|
||||
FRAME_stand30,
|
||||
gunner_frames_stand,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -192,27 +245,28 @@ gunner_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gunner_move_stand;
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_walk[] = {
|
||||
{ai_walk, 0, NULL},
|
||||
static mframe_t gunner_frames_walk[] = {
|
||||
{ai_walk, 0, gunner_footstep},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 2, gunner_footstep},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
{ai_walk, 4, NULL}
|
||||
{ai_walk, 4, gunner_footstep}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_walk = {
|
||||
mmove_t gunner_move_walk =
|
||||
{
|
||||
FRAME_walk07,
|
||||
FRAME_walk19,
|
||||
gunner_frames_walk,
|
||||
NULL
|
||||
FRAME_walk19,
|
||||
gunner_frames_walk,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -226,22 +280,23 @@ gunner_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gunner_move_walk;
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_run[] = {
|
||||
static mframe_t gunner_frames_run[] = {
|
||||
{ai_run, 26, NULL},
|
||||
{ai_run, 9, NULL},
|
||||
{ai_run, 9, gunner_footstep},
|
||||
{ai_run, 9, NULL},
|
||||
{ai_run, 9, monster_done_dodge},
|
||||
{ai_run, 15, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, gunner_footstep},
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 6, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_run = {
|
||||
mmove_t gunner_move_run =
|
||||
{
|
||||
FRAME_run01,
|
||||
FRAME_run08,
|
||||
gunner_frames_run,
|
||||
NULL
|
||||
gunner_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -264,20 +319,21 @@ gunner_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_runandshoot[] = {
|
||||
static mframe_t gunner_frames_runandshoot[] = {
|
||||
{ai_run, 32, NULL},
|
||||
{ai_run, 15, NULL},
|
||||
{ai_run, 15, gunner_footstep},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 18, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 8, gunner_footstep},
|
||||
{ai_run, 20, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_runandshoot = {
|
||||
mmove_t gunner_move_runandshoot =
|
||||
{
|
||||
FRAME_runs01,
|
||||
FRAME_runs06,
|
||||
FRAME_runs06,
|
||||
gunner_frames_runandshoot,
|
||||
NULL
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -291,7 +347,7 @@ gunner_runandshoot(edict_t *self)
|
|||
self->monsterinfo.currentmove = &gunner_move_runandshoot;
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_pain3[] = {
|
||||
static mframe_t gunner_frames_pain3[] = {
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
|
@ -299,35 +355,37 @@ mframe_t gunner_frames_pain3[] = {
|
|||
{ai_move, 1, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_pain3 = {
|
||||
mmove_t gunner_move_pain3 =
|
||||
{
|
||||
FRAME_pain301,
|
||||
FRAME_pain305,
|
||||
gunner_frames_pain3,
|
||||
gunner_run
|
||||
FRAME_pain305,
|
||||
gunner_frames_pain3,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
mframe_t gunner_frames_pain2[] = {
|
||||
static mframe_t gunner_frames_pain2[] = {
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 11, NULL},
|
||||
{ai_move, 6, NULL},
|
||||
{ai_move, 6, gunner_footstep},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -7, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -7, NULL}
|
||||
{ai_move, -7, gunner_footstep}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_pain2 = {
|
||||
mmove_t gunner_move_pain2 =
|
||||
{
|
||||
FRAME_pain201,
|
||||
FRAME_pain208,
|
||||
gunner_frames_pain2,
|
||||
gunner_run
|
||||
FRAME_pain208,
|
||||
gunner_frames_pain2,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
mframe_t gunner_frames_pain1[] = {
|
||||
static mframe_t gunner_frames_pain1[] = {
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, gunner_footstep},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -337,23 +395,25 @@ mframe_t gunner_frames_pain1[] = {
|
|||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, gunner_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, gunner_footstep},
|
||||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_pain1 = {
|
||||
mmove_t gunner_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain118,
|
||||
gunner_frames_pain1,
|
||||
gunner_run
|
||||
FRAME_pain118,
|
||||
gunner_frames_pain1,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
void
|
||||
gunner_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
gunner_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -430,7 +490,7 @@ gunner_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_death[] = {
|
||||
static mframe_t gunner_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -444,16 +504,18 @@ mframe_t gunner_frames_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_death = {
|
||||
mmove_t gunner_move_death =
|
||||
{
|
||||
FRAME_death01,
|
||||
FRAME_death11,
|
||||
gunner_frames_death,
|
||||
gunner_dead
|
||||
FRAME_death11,
|
||||
gunner_frames_death,
|
||||
gunner_dead
|
||||
};
|
||||
|
||||
void
|
||||
gunner_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
gunner_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage /* unused */,
|
||||
vec3_t point)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -469,15 +531,18 @@ gunner_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -504,14 +569,6 @@ gunner_duck_down(edict_t *self)
|
|||
|
||||
self->monsterinfo.aiflags |= AI_DUCKED;
|
||||
|
||||
if (skill->value >= SKILL_HARD)
|
||||
{
|
||||
if (random() > 0.5)
|
||||
{
|
||||
GunnerGrenade(self);
|
||||
}
|
||||
}
|
||||
|
||||
self->maxs[2] = self->monsterinfo.base_height - 32;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
|
||||
|
@ -523,8 +580,23 @@ gunner_duck_down(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_duck[] = {
|
||||
{ai_move, 1, gunner_duck_down},
|
||||
static void
|
||||
gunner_duck_down_think(edict_t *self)
|
||||
{
|
||||
gunner_duck_down(self);
|
||||
|
||||
/* rogue code calls duck_down twice, so move this here */
|
||||
if (skill->value >= SKILL_HARD)
|
||||
{
|
||||
if (random() > 0.5)
|
||||
{
|
||||
GunnerGrenade(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mframe_t gunner_frames_duck[] = {
|
||||
{ai_move, 1, gunner_duck_down_think},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, monster_duck_hold},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -534,11 +606,12 @@ mframe_t gunner_frames_duck[] = {
|
|||
{ai_move, -1, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_duck = {
|
||||
mmove_t gunner_move_duck =
|
||||
{
|
||||
FRAME_duck01,
|
||||
FRAME_duck08,
|
||||
gunner_frames_duck,
|
||||
gunner_run
|
||||
FRAME_duck08,
|
||||
gunner_frames_duck,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
/* gunner dodge moved below so I know about attack sequences */
|
||||
|
@ -758,9 +831,9 @@ GunnerGrenade(edict_t *self)
|
|||
monster_fire_grenade(self, start, aim, 50, 600, flash_number);
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_attack_chain[] = {
|
||||
static mframe_t gunner_frames_attack_chain[] = {
|
||||
{ai_charge, 0, gunner_opengun},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, gunner_footstep},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -768,14 +841,15 @@ mframe_t gunner_frames_attack_chain[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_attack_chain = {
|
||||
mmove_t gunner_move_attack_chain =
|
||||
{
|
||||
FRAME_attak209,
|
||||
FRAME_attak215,
|
||||
gunner_frames_attack_chain,
|
||||
gunner_fire_chain
|
||||
FRAME_attak215,
|
||||
gunner_frames_attack_chain,
|
||||
gunner_fire_chain
|
||||
};
|
||||
|
||||
mframe_t gunner_frames_fire_chain[] = {
|
||||
static mframe_t gunner_frames_fire_chain[] = {
|
||||
{ai_charge, 0, GunnerFire},
|
||||
{ai_charge, 0, GunnerFire},
|
||||
{ai_charge, 0, GunnerFire},
|
||||
|
@ -786,28 +860,30 @@ mframe_t gunner_frames_fire_chain[] = {
|
|||
{ai_charge, 0, GunnerFire}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_fire_chain = {
|
||||
mmove_t gunner_move_fire_chain =
|
||||
{
|
||||
FRAME_attak216,
|
||||
FRAME_attak223,
|
||||
gunner_frames_fire_chain,
|
||||
gunner_refire_chain
|
||||
FRAME_attak223,
|
||||
gunner_frames_fire_chain,
|
||||
gunner_refire_chain
|
||||
};
|
||||
|
||||
mframe_t gunner_frames_endfire_chain[] = {
|
||||
static mframe_t gunner_frames_endfire_chain[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
{ai_charge, 0, gunner_footstep}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_endfire_chain = {
|
||||
mmove_t gunner_move_endfire_chain =
|
||||
{
|
||||
FRAME_attak224,
|
||||
FRAME_attak230,
|
||||
gunner_frames_endfire_chain,
|
||||
gunner_run
|
||||
FRAME_attak230,
|
||||
gunner_frames_endfire_chain,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -828,7 +904,7 @@ gunner_blind_check(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_attack_grenade[] = {
|
||||
static mframe_t gunner_frames_attack_grenade[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -852,11 +928,12 @@ mframe_t gunner_frames_attack_grenade[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t gunner_move_attack_grenade = {
|
||||
mmove_t gunner_move_attack_grenade =
|
||||
{
|
||||
FRAME_attak101,
|
||||
FRAME_attak121,
|
||||
gunner_frames_attack_grenade,
|
||||
gunner_run
|
||||
gunner_frames_attack_grenade,
|
||||
gunner_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1028,7 +1105,7 @@ gunner_jump_wait_land(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t gunner_frames_jump[] = {
|
||||
static mframe_t gunner_frames_jump[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1048,7 +1125,7 @@ mmove_t gunner_move_jump = {
|
|||
gunner_run
|
||||
};
|
||||
|
||||
mframe_t gunner_frames_jump2[] = {
|
||||
static mframe_t gunner_frames_jump2[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
|
@ -1211,6 +1288,11 @@ SP_monster_gunner(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
sound_death = gi.soundindex("gunner/death1.wav");
|
||||
sound_pain = gi.soundindex("gunner/gunpain2.wav");
|
||||
sound_pain2 = gi.soundindex("gunner/gunpain1.wav");
|
||||
|
|
|
@ -85,7 +85,7 @@ hover_search(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t hover_frames_stand[] = {
|
||||
static mframe_t hover_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -125,7 +125,7 @@ mmove_t hover_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t hover_frames_pain3[] = {
|
||||
static mframe_t hover_frames_pain3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -144,7 +144,7 @@ mmove_t hover_move_pain3 = {
|
|||
hover_run
|
||||
};
|
||||
|
||||
mframe_t hover_frames_pain2[] = {
|
||||
static mframe_t hover_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -166,7 +166,7 @@ mmove_t hover_move_pain2 = {
|
|||
hover_run
|
||||
};
|
||||
|
||||
mframe_t hover_frames_pain1[] = {
|
||||
static mframe_t hover_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
|
@ -204,7 +204,7 @@ mmove_t hover_move_pain1 = {
|
|||
hover_run
|
||||
};
|
||||
|
||||
mframe_t hover_frames_walk[] = {
|
||||
static mframe_t hover_frames_walk[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
|
@ -249,7 +249,7 @@ mmove_t hover_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t hover_frames_run[] = {
|
||||
static mframe_t hover_frames_run[] = {
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
|
@ -294,7 +294,7 @@ mmove_t hover_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t hover_frames_death1[] = {
|
||||
static mframe_t hover_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -315,7 +315,7 @@ mmove_t hover_move_death1 = {
|
|||
hover_dead
|
||||
};
|
||||
|
||||
mframe_t hover_frames_start_attack[] = {
|
||||
static mframe_t hover_frames_start_attack[] = {
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 1, NULL}
|
||||
|
@ -328,7 +328,7 @@ mmove_t hover_move_start_attack = {
|
|||
hover_attack
|
||||
};
|
||||
|
||||
mframe_t hover_frames_attack1[] = {
|
||||
static mframe_t hover_frames_attack1[] = {
|
||||
{ai_charge, -10, hover_fire_blaster},
|
||||
{ai_charge, -10, hover_fire_blaster},
|
||||
{ai_charge, 0, hover_reattack},
|
||||
|
@ -341,7 +341,7 @@ mmove_t hover_move_attack1 = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t hover_frames_end_attack[] = {
|
||||
static mframe_t hover_frames_end_attack[] = {
|
||||
{ai_charge, 1, NULL},
|
||||
{ai_charge, 1, NULL}
|
||||
};
|
||||
|
@ -353,7 +353,7 @@ mmove_t hover_move_end_attack = {
|
|||
hover_run
|
||||
};
|
||||
|
||||
mframe_t hover_frames_start_attack2[] = {
|
||||
static mframe_t hover_frames_start_attack2[] = {
|
||||
{ai_charge, 15, NULL},
|
||||
{ai_charge, 15, NULL},
|
||||
{ai_charge, 15, NULL}
|
||||
|
@ -366,7 +366,7 @@ mmove_t hover_move_start_attack2 = {
|
|||
hover_attack
|
||||
};
|
||||
|
||||
mframe_t hover_frames_attack2[] = {
|
||||
static mframe_t hover_frames_attack2[] = {
|
||||
{ai_charge, 10, hover_fire_blaster},
|
||||
{ai_charge, 10, hover_fire_blaster},
|
||||
{ai_charge, 10, hover_reattack},
|
||||
|
@ -379,7 +379,7 @@ mmove_t hover_move_attack2 = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t hover_frames_end_attack2[] = {
|
||||
static mframe_t hover_frames_end_attack2[] = {
|
||||
{ai_charge, 15, NULL},
|
||||
{ai_charge, 15, NULL}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Infantry.
|
||||
*
|
||||
|
@ -23,7 +42,34 @@ static int sound_sight;
|
|||
static int sound_search;
|
||||
static int sound_idle;
|
||||
|
||||
mframe_t infantry_frames_stand[] = {
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
void
|
||||
infantry_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("infantry/step1.wav");
|
||||
sound_step2 = gi.soundindex("infantry/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static mframe_t infantry_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -48,9 +94,10 @@ mframe_t infantry_frames_stand[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_stand = {
|
||||
mmove_t infantry_move_stand =
|
||||
{
|
||||
FRAME_stand50,
|
||||
FRAME_stand71,
|
||||
FRAME_stand71,
|
||||
infantry_frames_stand,
|
||||
NULL
|
||||
};
|
||||
|
@ -66,13 +113,13 @@ infantry_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &infantry_move_stand;
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_fidget[] = {
|
||||
static mframe_t infantry_frames_fidget[] = {
|
||||
{ai_stand, 1, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 1, NULL},
|
||||
{ai_stand, 3, NULL},
|
||||
{ai_stand, 6, NULL},
|
||||
{ai_stand, 3, NULL},
|
||||
{ai_stand, 3, infantry_footstep},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -114,15 +161,16 @@ mframe_t infantry_frames_fidget[] = {
|
|||
{ai_stand, -3, NULL},
|
||||
{ai_stand, -2, NULL},
|
||||
{ai_stand, -3, NULL},
|
||||
{ai_stand, -3, NULL},
|
||||
{ai_stand, -3, infantry_footstep},
|
||||
{ai_stand, -2, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_fidget = {
|
||||
mmove_t infantry_move_fidget =
|
||||
{
|
||||
FRAME_stand01,
|
||||
FRAME_stand49,
|
||||
infantry_frames_fidget,
|
||||
infantry_stand
|
||||
FRAME_stand49,
|
||||
infantry_frames_fidget,
|
||||
infantry_stand
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -137,14 +185,14 @@ infantry_fidget(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_walk[] = {
|
||||
{ai_walk, 5, NULL},
|
||||
static mframe_t infantry_frames_walk[] = {
|
||||
{ai_walk, 5, infantry_footstep},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 6, infantry_footstep},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
|
@ -152,10 +200,11 @@ mframe_t infantry_frames_walk[] = {
|
|||
{ai_walk, 5, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_walk = {
|
||||
mmove_t infantry_move_walk =
|
||||
{
|
||||
FRAME_walk03,
|
||||
FRAME_walk14,
|
||||
infantry_frames_walk,
|
||||
FRAME_walk14,
|
||||
infantry_frames_walk,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -170,28 +219,29 @@ infantry_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &infantry_move_walk;
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_run[] = {
|
||||
static mframe_t infantry_frames_run[] = {
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 20, NULL},
|
||||
{ai_run, 20, infantry_footstep},
|
||||
{ai_run, 5, NULL},
|
||||
{ai_run, 7, monster_done_dodge},
|
||||
{ai_run, 30, NULL},
|
||||
{ai_run, 35, NULL},
|
||||
{ai_run, 35, infantry_footstep},
|
||||
{ai_run, 2, NULL},
|
||||
{ai_run, 6, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_run = {
|
||||
mmove_t infantry_move_run =
|
||||
{
|
||||
FRAME_run01,
|
||||
FRAME_run08,
|
||||
infantry_frames_run,
|
||||
FRAME_run08,
|
||||
infantry_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
infantry_run(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -208,48 +258,51 @@ infantry_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_pain1[] = {
|
||||
static mframe_t infantry_frames_pain1[] = {
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -1, infantry_footstep},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 6, NULL},
|
||||
{ai_move, 2, NULL}
|
||||
{ai_move, 2, infantry_footstep}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_pain1 = {
|
||||
mmove_t infantry_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain110,
|
||||
infantry_frames_pain1,
|
||||
infantry_run
|
||||
};
|
||||
|
||||
mframe_t infantry_frames_pain2[] = {
|
||||
static mframe_t infantry_frames_pain2[] = {
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -2, infantry_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 5, NULL},
|
||||
{ai_move, 2, NULL}
|
||||
{ai_move, 2, infantry_footstep}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_pain2 = {
|
||||
mmove_t infantry_move_pain2 =
|
||||
{
|
||||
FRAME_pain201,
|
||||
FRAME_pain210,
|
||||
infantry_frames_pain2,
|
||||
infantry_run
|
||||
FRAME_pain210,
|
||||
infantry_frames_pain2,
|
||||
infantry_run
|
||||
};
|
||||
|
||||
void
|
||||
infantry_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
infantry_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -394,16 +447,16 @@ infantry_dead(edict_t *self)
|
|||
M_FlyCheck(self);
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_death1[] = {
|
||||
static mframe_t infantry_frames_death1[] = {
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, -4, infantry_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -1, infantry_footstep},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
|
@ -417,22 +470,23 @@ mframe_t infantry_frames_death1[] = {
|
|||
{ai_move, -3, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_death1 = {
|
||||
mmove_t infantry_move_death1 =
|
||||
{
|
||||
FRAME_death101,
|
||||
FRAME_death120,
|
||||
infantry_frames_death1,
|
||||
infantry_dead
|
||||
FRAME_death120,
|
||||
infantry_frames_death1,
|
||||
infantry_dead
|
||||
};
|
||||
|
||||
/* Off with his head */
|
||||
mframe_t infantry_frames_death2[] = {
|
||||
static mframe_t infantry_frames_death2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 5, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
{ai_move, 1, infantry_footstep},
|
||||
{ai_move, 1, infantry_footstep},
|
||||
{ai_move, 4, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -453,14 +507,15 @@ mframe_t infantry_frames_death2[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_death2 = {
|
||||
mmove_t infantry_move_death2 =
|
||||
{
|
||||
FRAME_death201,
|
||||
FRAME_death225,
|
||||
FRAME_death225,
|
||||
infantry_frames_death2,
|
||||
infantry_dead
|
||||
};
|
||||
|
||||
mframe_t infantry_frames_death3[] = {
|
||||
static mframe_t infantry_frames_death3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -472,7 +527,8 @@ mframe_t infantry_frames_death3[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_death3 = {
|
||||
mmove_t infantry_move_death3 =
|
||||
{
|
||||
FRAME_death301,
|
||||
FRAME_death309,
|
||||
infantry_frames_death3,
|
||||
|
@ -480,8 +536,9 @@ mmove_t infantry_move_death3 = {
|
|||
};
|
||||
|
||||
void
|
||||
infantry_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
infantry_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -497,15 +554,18 @@ infantry_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /
|
|||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -539,12 +599,12 @@ infantry_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_duck[] = {
|
||||
static mframe_t infantry_frames_duck[] = {
|
||||
{ai_move, -2, monster_duck_down},
|
||||
{ai_move, -5, monster_duck_hold},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 4, monster_duck_up},
|
||||
{ai_move, 0, NULL}
|
||||
{ai_move, 0, infantry_footstep}
|
||||
};
|
||||
|
||||
mmove_t infantry_move_duck = {
|
||||
|
@ -599,7 +659,7 @@ infantry_fire_prep(edict_t *self)
|
|||
self->monsterinfo.pausetime = level.time + n * FRAMETIME;
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_attack1[] = {
|
||||
static mframe_t infantry_frames_attack1[] = {
|
||||
{ai_charge, -3, NULL}, /* 101 */
|
||||
{ai_charge, -2, NULL}, /* 102 */
|
||||
{ai_charge, -1, infantry_fire_prep}, /* 103 */
|
||||
|
@ -653,11 +713,11 @@ infantry_smack(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_attack2[] = {
|
||||
static mframe_t infantry_frames_attack2[] = {
|
||||
{ai_charge, 3, NULL},
|
||||
{ai_charge, 6, NULL},
|
||||
{ai_charge, 0, infantry_swing},
|
||||
{ai_charge, 8, NULL},
|
||||
{ai_charge, 8, infantry_footstep},
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, 8, infantry_smack},
|
||||
{ai_charge, 6, NULL},
|
||||
|
@ -748,7 +808,7 @@ infantry_jump_wait_land(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t infantry_frames_jump[] = {
|
||||
static mframe_t infantry_frames_jump[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -768,7 +828,7 @@ mmove_t infantry_move_jump = {
|
|||
infantry_run
|
||||
};
|
||||
|
||||
mframe_t infantry_frames_jump2[] = {
|
||||
static mframe_t infantry_frames_jump2[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
|
@ -928,6 +988,11 @@ SP_monster_infantry(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
sound_pain1 = gi.soundindex("infantry/infpain1.wav");
|
||||
sound_pain2 = gi.soundindex("infantry/infpain2.wav");
|
||||
sound_die1 = gi.soundindex("infantry/infdeth1.wav");
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The insane earth soldiers.
|
||||
*
|
||||
|
@ -15,6 +34,11 @@ static int sound_shake;
|
|||
static int sound_moan;
|
||||
static int sound_scream[8];
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
static int sound_step3;
|
||||
static int sound_step4;
|
||||
|
||||
void insane_stand(edict_t *self);
|
||||
void insane_dead(edict_t *self);
|
||||
void insane_cross(edict_t *self);
|
||||
|
@ -24,6 +48,43 @@ void insane_checkdown(edict_t *self);
|
|||
void insane_checkup(edict_t *self);
|
||||
void insane_onground(edict_t *self);
|
||||
|
||||
void
|
||||
insane_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0 || sound_step3 == 0 || sound_step4 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("player/step1.wav");
|
||||
sound_step2 = gi.soundindex("player/step2.wav");
|
||||
sound_step3 = gi.soundindex("player/step3.wav");
|
||||
sound_step4 = gi.soundindex("player/step4.wav");
|
||||
}
|
||||
|
||||
int i;
|
||||
i = randk() % 4;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 0.7, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 0.7, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step3, 0.7, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step4, 0.7, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
insane_fist(edict_t *self)
|
||||
{
|
||||
|
@ -80,7 +141,7 @@ insane_scream(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_scream[rand() % 8], 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t insane_frames_stand_normal[] = {
|
||||
static mframe_t insane_frames_stand_normal[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -89,14 +150,15 @@ mframe_t insane_frames_stand_normal[] = {
|
|||
{ai_stand, 0, insane_checkdown}
|
||||
};
|
||||
|
||||
mmove_t insane_move_stand_normal = {
|
||||
mmove_t insane_move_stand_normal =
|
||||
{
|
||||
FRAME_stand60,
|
||||
FRAME_stand65,
|
||||
FRAME_stand65,
|
||||
insane_frames_stand_normal,
|
||||
insane_stand
|
||||
};
|
||||
|
||||
mframe_t insane_frames_stand_insane[] = {
|
||||
static mframe_t insane_frames_stand_insane[] = {
|
||||
{ai_stand, 0, insane_shake},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -129,14 +191,15 @@ mframe_t insane_frames_stand_insane[] = {
|
|||
{ai_stand, 0, insane_checkdown}
|
||||
};
|
||||
|
||||
mmove_t insane_move_stand_insane = {
|
||||
mmove_t insane_move_stand_insane =
|
||||
{
|
||||
FRAME_stand65,
|
||||
FRAME_stand94,
|
||||
insane_frames_stand_insane,
|
||||
insane_frames_stand_insane,
|
||||
insane_stand
|
||||
};
|
||||
|
||||
mframe_t insane_frames_uptodown[] = {
|
||||
static mframe_t insane_frames_uptodown[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -182,43 +245,45 @@ mframe_t insane_frames_uptodown[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_uptodown = {
|
||||
mmove_t insane_move_uptodown =
|
||||
{
|
||||
FRAME_stand1,
|
||||
FRAME_stand40,
|
||||
insane_frames_uptodown,
|
||||
insane_onground
|
||||
};
|
||||
|
||||
mframe_t insane_frames_downtoup[] = {
|
||||
{ai_move, -0.7, NULL}, /* 41 */
|
||||
{ai_move, -1.2, NULL}, /* 42 */
|
||||
{ai_move, -1.5, NULL}, /* 43 */
|
||||
{ai_move, -4.5, NULL}, /* 44 */
|
||||
{ai_move, -3.5, NULL}, /* 45 */
|
||||
{ai_move, -0.2, NULL}, /* 46 */
|
||||
{ai_move, 0, NULL}, /* 47 */
|
||||
{ai_move, -1.3, NULL}, /* 48 */
|
||||
{ai_move, -3, NULL}, /* 49 */
|
||||
{ai_move, -2, NULL}, /* 50 */
|
||||
{ai_move, 0, NULL}, /* 51 */
|
||||
{ai_move, 0, NULL}, /* 52 */
|
||||
{ai_move, 0, NULL}, /* 53 */
|
||||
{ai_move, -3.3, NULL}, /* 54 */
|
||||
{ai_move, -1.6, NULL}, /* 55 */
|
||||
{ai_move, -0.3, NULL}, /* 56 */
|
||||
{ai_move, 0, NULL}, /* 57 */
|
||||
{ai_move, 0, NULL}, /* 58 */
|
||||
{ai_move, 0, NULL} /* 59 */
|
||||
static mframe_t insane_frames_downtoup[] = {
|
||||
{ai_move, -0.7, NULL}, /* 41 */
|
||||
{ai_move, -1.2, NULL}, /* 42 */
|
||||
{ai_move, -1.5, NULL}, /* 43 */
|
||||
{ai_move, -4.5, NULL}, /* 44 */
|
||||
{ai_move, -3.5, NULL}, /* 45 */
|
||||
{ai_move, -0.2, NULL}, /* 46 */
|
||||
{ai_move, 0, NULL}, /* 47 */
|
||||
{ai_move, -1.3, NULL}, /* 48 */
|
||||
{ai_move, -3, NULL}, /* 49 */
|
||||
{ai_move, -2, NULL}, /* 50 */
|
||||
{ai_move, 0, NULL}, /* 51 */
|
||||
{ai_move, 0, NULL}, /* 52 */
|
||||
{ai_move, 0, NULL}, /* 53 */
|
||||
{ai_move, -3.3, NULL}, /* 54 */
|
||||
{ai_move, -1.6, NULL}, /* 55 */
|
||||
{ai_move, -0.3, NULL}, /* 56 */
|
||||
{ai_move, 0, NULL}, /* 57 */
|
||||
{ai_move, 0, NULL}, /* 58 */
|
||||
{ai_move, 0, NULL} /* 59 */
|
||||
};
|
||||
|
||||
mmove_t insane_move_downtoup = {
|
||||
mmove_t insane_move_downtoup =
|
||||
{
|
||||
FRAME_stand41,
|
||||
FRAME_stand59,
|
||||
insane_frames_downtoup,
|
||||
insane_stand
|
||||
FRAME_stand59,
|
||||
insane_frames_downtoup,
|
||||
insane_stand
|
||||
};
|
||||
|
||||
mframe_t insane_frames_jumpdown[] = {
|
||||
static mframe_t insane_frames_jumpdown[] = {
|
||||
{ai_move, 0.2, NULL},
|
||||
{ai_move, 11.5, NULL},
|
||||
{ai_move, 5.1, NULL},
|
||||
|
@ -226,15 +291,16 @@ mframe_t insane_frames_jumpdown[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_jumpdown = {
|
||||
mmove_t insane_move_jumpdown =
|
||||
{
|
||||
FRAME_stand96,
|
||||
FRAME_stand100,
|
||||
FRAME_stand100,
|
||||
insane_frames_jumpdown,
|
||||
insane_onground
|
||||
};
|
||||
|
||||
mframe_t insane_frames_down[] = {
|
||||
{ai_move, 0, NULL}, /* 100 */
|
||||
static mframe_t insane_frames_down[] = {
|
||||
{ai_move, 0, NULL}, /* 100 */
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -244,7 +310,7 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* 110 */
|
||||
{ai_move, 0, NULL}, /* 110 */
|
||||
{ai_move, -1.7, NULL},
|
||||
{ai_move, -1.6, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -254,7 +320,7 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* 120 */
|
||||
{ai_move, 0, NULL}, /* 120 */
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -264,7 +330,7 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* 130 */
|
||||
{ai_move, 0, NULL}, /* 130 */
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, insane_moan},
|
||||
|
@ -274,7 +340,7 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* 140 */
|
||||
{ai_move, 0, NULL}, /* 140 */
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -284,7 +350,7 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}, /* 150 */
|
||||
{ai_move, 0, NULL}, /* 150 */
|
||||
{ai_move, 0.5, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -0.2, insane_scream},
|
||||
|
@ -294,95 +360,100 @@ mframe_t insane_frames_down[] = {
|
|||
{ai_move, 0.6, NULL},
|
||||
{ai_move, 0.8, NULL},
|
||||
{ai_move, 0.7, NULL},
|
||||
{ai_move, 0, insane_checkup} /* 160 */
|
||||
{ai_move, 0, insane_checkup} /* 160 */
|
||||
};
|
||||
|
||||
mmove_t insane_move_down = {
|
||||
mmove_t insane_move_down =
|
||||
{
|
||||
FRAME_stand100,
|
||||
FRAME_stand160,
|
||||
FRAME_stand160,
|
||||
insane_frames_down,
|
||||
insane_onground
|
||||
};
|
||||
|
||||
mframe_t insane_frames_walk_normal[] = {
|
||||
static mframe_t insane_frames_walk_normal[] = {
|
||||
{ai_walk, 0, insane_scream},
|
||||
{ai_walk, 2.5, NULL},
|
||||
{ai_walk, 3.5, NULL},
|
||||
{ai_walk, 1.7, NULL},
|
||||
{ai_walk, 2.3, NULL},
|
||||
{ai_walk, 2.4, NULL},
|
||||
{ai_walk, 2.2, NULL},
|
||||
{ai_walk, 2.2, insane_footstep},
|
||||
{ai_walk, 4.2, NULL},
|
||||
{ai_walk, 5.6, NULL},
|
||||
{ai_walk, 3.3, NULL},
|
||||
{ai_walk, 2.4, NULL},
|
||||
{ai_walk, 0.9, NULL},
|
||||
{ai_walk, 0, NULL}
|
||||
{ai_walk, 0, insane_footstep}
|
||||
};
|
||||
|
||||
mmove_t insane_move_walk_normal = {
|
||||
mmove_t insane_move_walk_normal =
|
||||
{
|
||||
FRAME_walk27,
|
||||
FRAME_walk39,
|
||||
insane_frames_walk_normal,
|
||||
insane_walk
|
||||
};
|
||||
|
||||
mmove_t insane_move_run_normal =
|
||||
{
|
||||
FRAME_walk27,
|
||||
FRAME_walk39,
|
||||
insane_frames_walk_normal,
|
||||
insane_walk
|
||||
insane_run
|
||||
};
|
||||
|
||||
mmove_t insane_move_run_normal = {
|
||||
FRAME_walk27,
|
||||
FRAME_walk39,
|
||||
insane_frames_walk_normal,
|
||||
insane_run
|
||||
static mframe_t insane_frames_walk_insane[] = {
|
||||
{ai_walk, 0, insane_scream}, /* walk 1 */
|
||||
{ai_walk, 3.4, NULL}, /* walk 2 */
|
||||
{ai_walk, 3.6, NULL}, /* 3 */
|
||||
{ai_walk, 2.9, NULL}, /* 4 */
|
||||
{ai_walk, 2.2, NULL}, /* 5 */
|
||||
{ai_walk, 2.6, NULL}, /* 6 */
|
||||
{ai_walk, 0, insane_footstep}, /* 7 */
|
||||
{ai_walk, 0.7, NULL}, /* 8 */
|
||||
{ai_walk, 4.8, NULL}, /* 9 */
|
||||
{ai_walk, 5.3, NULL}, /* 10 */
|
||||
{ai_walk, 1.1, NULL}, /* 11 */
|
||||
{ai_walk, 2, insane_footstep}, /* 12 */
|
||||
{ai_walk, 0.5, NULL}, /* 13 */
|
||||
{ai_walk, 0, NULL}, /* 14 */
|
||||
{ai_walk, 0, NULL}, /* 15 */
|
||||
{ai_walk, 4.9, NULL}, /* 16 */
|
||||
{ai_walk, 6.7, NULL}, /* 17 */
|
||||
{ai_walk, 3.8, NULL}, /* 18 */
|
||||
{ai_walk, 2, insane_footstep}, /* 19 */
|
||||
{ai_walk, 0.2, NULL}, /* 20 */
|
||||
{ai_walk, 0, NULL}, /* 21 */
|
||||
{ai_walk, 3.4, NULL}, /* 22 */
|
||||
{ai_walk, 6.4, NULL}, /* 23 */
|
||||
{ai_walk, 5, NULL}, /* 24 */
|
||||
{ai_walk, 1.8, insane_footstep}, /* 25 */
|
||||
{ai_walk, 0, NULL} /* 26 */
|
||||
};
|
||||
|
||||
mframe_t insane_frames_walk_insane[] = {
|
||||
{ai_walk, 0, insane_scream}, /* walk 1 */
|
||||
{ai_walk, 3.4, NULL}, /* walk 2 */
|
||||
{ai_walk, 3.6, NULL}, /* 3 */
|
||||
{ai_walk, 2.9, NULL}, /* 4 */
|
||||
{ai_walk, 2.2, NULL}, /* 5 */
|
||||
{ai_walk, 2.6, NULL}, /* 6 */
|
||||
{ai_walk, 0, NULL}, /* 7 */
|
||||
{ai_walk, 0.7, NULL}, /* 8 */
|
||||
{ai_walk, 4.8, NULL}, /* 9 */
|
||||
{ai_walk, 5.3, NULL}, /* 10 */
|
||||
{ai_walk, 1.1, NULL}, /* 11 */
|
||||
{ai_walk, 2, NULL}, /* 12 */
|
||||
{ai_walk, 0.5, NULL}, /* 13 */
|
||||
{ai_walk, 0, NULL}, /* 14 */
|
||||
{ai_walk, 0, NULL}, /* 15 */
|
||||
{ai_walk, 4.9, NULL}, /* 16 */
|
||||
{ai_walk, 6.7, NULL}, /* 17 */
|
||||
{ai_walk, 3.8, NULL}, /* 18 */
|
||||
{ai_walk, 2, NULL}, /* 19 */
|
||||
{ai_walk, 0.2, NULL}, /* 20 */
|
||||
{ai_walk, 0, NULL}, /* 21 */
|
||||
{ai_walk, 3.4, NULL}, /* 22 */
|
||||
{ai_walk, 6.4, NULL}, /* 23 */
|
||||
{ai_walk, 5, NULL}, /* 24 */
|
||||
{ai_walk, 1.8, NULL}, /* 25 */
|
||||
{ai_walk, 0, NULL} /* 26 */
|
||||
};
|
||||
|
||||
mmove_t insane_move_walk_insane = {
|
||||
mmove_t insane_move_walk_insane =
|
||||
{
|
||||
FRAME_walk1,
|
||||
FRAME_walk26,
|
||||
insane_frames_walk_insane,
|
||||
insane_walk
|
||||
};
|
||||
|
||||
mmove_t insane_move_run_insane = {
|
||||
mmove_t insane_move_run_insane =
|
||||
{
|
||||
FRAME_walk1,
|
||||
FRAME_walk26,
|
||||
FRAME_walk26,
|
||||
insane_frames_walk_insane,
|
||||
insane_run
|
||||
};
|
||||
|
||||
mframe_t insane_frames_stand_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
static mframe_t insane_frames_stand_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, insane_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -391,14 +462,15 @@ mframe_t insane_frames_stand_pain[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_stand_pain = {
|
||||
mmove_t insane_move_stand_pain =
|
||||
{
|
||||
FRAME_st_pain2,
|
||||
FRAME_st_pain12,
|
||||
insane_frames_stand_pain,
|
||||
insane_run
|
||||
};
|
||||
|
||||
mframe_t insane_frames_stand_death[] = {
|
||||
static mframe_t insane_frames_stand_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -418,14 +490,15 @@ mframe_t insane_frames_stand_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_stand_death = {
|
||||
mmove_t insane_move_stand_death =
|
||||
{
|
||||
FRAME_st_death2,
|
||||
FRAME_st_death18,
|
||||
insane_frames_stand_death,
|
||||
insane_dead
|
||||
insane_dead
|
||||
};
|
||||
|
||||
mframe_t insane_frames_crawl[] = {
|
||||
static mframe_t insane_frames_crawl[] = {
|
||||
{ai_walk, 0, insane_scream},
|
||||
{ai_walk, 1.5, NULL},
|
||||
{ai_walk, 2.1, NULL},
|
||||
|
@ -437,21 +510,23 @@ mframe_t insane_frames_crawl[] = {
|
|||
{ai_walk, 2.4, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_crawl = {
|
||||
mmove_t insane_move_crawl =
|
||||
{
|
||||
FRAME_crawl1,
|
||||
FRAME_crawl9,
|
||||
insane_frames_crawl,
|
||||
NULL
|
||||
};
|
||||
|
||||
mmove_t insane_move_runcrawl = {
|
||||
mmove_t insane_move_runcrawl =
|
||||
{
|
||||
FRAME_crawl1,
|
||||
FRAME_crawl9,
|
||||
insane_frames_crawl,
|
||||
insane_frames_crawl,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t insane_frames_crawl_pain[] = {
|
||||
static mframe_t insane_frames_crawl_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -463,14 +538,15 @@ mframe_t insane_frames_crawl_pain[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_crawl_pain = {
|
||||
mmove_t insane_move_crawl_pain =
|
||||
{
|
||||
FRAME_cr_pain2,
|
||||
FRAME_cr_pain10,
|
||||
insane_frames_crawl_pain,
|
||||
insane_run
|
||||
};
|
||||
|
||||
mframe_t insane_frames_crawl_death[] = {
|
||||
static mframe_t insane_frames_crawl_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -480,14 +556,15 @@ mframe_t insane_frames_crawl_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_crawl_death = {
|
||||
mmove_t insane_move_crawl_death =
|
||||
{
|
||||
FRAME_cr_death10,
|
||||
FRAME_cr_death16,
|
||||
FRAME_cr_death16,
|
||||
insane_frames_crawl_death,
|
||||
insane_dead
|
||||
};
|
||||
|
||||
mframe_t insane_frames_cross[] = {
|
||||
static mframe_t insane_frames_cross[] = {
|
||||
{ai_move, 0, insane_moan},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -505,14 +582,15 @@ mframe_t insane_frames_cross[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_cross = {
|
||||
mmove_t insane_move_cross =
|
||||
{
|
||||
FRAME_cross1,
|
||||
FRAME_cross15,
|
||||
FRAME_cross15,
|
||||
insane_frames_cross,
|
||||
insane_cross
|
||||
};
|
||||
|
||||
mframe_t insane_frames_struggle_cross[] = {
|
||||
static mframe_t insane_frames_struggle_cross[] = {
|
||||
{ai_move, 0, insane_scream},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -530,11 +608,12 @@ mframe_t insane_frames_struggle_cross[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t insane_move_struggle_cross = {
|
||||
mmove_t insane_move_struggle_cross =
|
||||
{
|
||||
FRAME_cross16,
|
||||
FRAME_cross30,
|
||||
insane_frames_struggle_cross,
|
||||
insane_cross
|
||||
insane_frames_struggle_cross,
|
||||
insane_cross
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -620,7 +699,8 @@ insane_run(edict_t *self)
|
|||
}
|
||||
|
||||
void
|
||||
insane_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
insane_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage)
|
||||
{
|
||||
int l, r;
|
||||
|
||||
|
@ -655,7 +735,8 @@ insane_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
l = 100;
|
||||
}
|
||||
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(va("player/male/pain%i_%i.wav", l, r)), 1, ATTN_IDLE, 0);
|
||||
gi.sound(self, CHAN_VOICE,
|
||||
gi.soundindex(va("player/male/pain%i_%i.wav", l, r)), 1, ATTN_IDLE, 0);
|
||||
|
||||
/* suppress screaming and moaning for 1 second so pain sound plays */
|
||||
self->fly_sound_debounce_time = level.time + 1;
|
||||
|
@ -666,7 +747,7 @@ insane_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
}
|
||||
|
||||
/* Don't go into pain frames if crucified. */
|
||||
if (self->spawnflags & 8)
|
||||
if (self->spawnflags & SPAWNFLAG_CRUSIFIED)
|
||||
{
|
||||
self->monsterinfo.currentmove = &insane_move_struggle_cross;
|
||||
return;
|
||||
|
@ -796,8 +877,9 @@ insane_dead(edict_t *self)
|
|||
}
|
||||
|
||||
void
|
||||
insane_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
insane_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -808,20 +890,22 @@ insane_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(
|
||||
"misc/udeath.wav"), 1, ATTN_IDLE, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_IDLE, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -831,7 +915,8 @@ insane_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
return;
|
||||
}
|
||||
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(va("player/male/death%i.wav", (rand() % 4) + 1)), 1, ATTN_IDLE, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(va("player/male/death%i.wav",
|
||||
(rand() % 4) + 1)), 1, ATTN_IDLE, 0);
|
||||
|
||||
self->deadflag = DEAD_DEAD;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
|
@ -873,6 +958,13 @@ SP_misc_insane(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
sound_step3 = 0;
|
||||
sound_step4 = 0;
|
||||
|
||||
sound_fist = gi.soundindex("insane/insane11.wav");
|
||||
sound_shake = gi.soundindex("insane/insane5.wav");
|
||||
sound_moan = gi.soundindex("insane/insane7.wav");
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Medic and Medic commander.
|
||||
*
|
||||
|
@ -35,6 +54,9 @@ static int sound_hook_hit;
|
|||
static int sound_hook_heal;
|
||||
static int sound_hook_retract;
|
||||
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
|
||||
/* commander sounds */
|
||||
static int commander_sound_idle1;
|
||||
static int commander_sound_pain1;
|
||||
|
@ -86,6 +108,29 @@ vec3_t reinforcement_position[] = {
|
|||
{0, -80, 0}
|
||||
};
|
||||
|
||||
void
|
||||
medic_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("medic/step1.wav");
|
||||
sound_step2 = gi.soundindex("medic/step2.wav");
|
||||
}
|
||||
|
||||
if (randk() % 2 == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cleanupHeal(edict_t *self, qboolean change_frame)
|
||||
{
|
||||
|
@ -340,6 +385,11 @@ medic_search(edict_t *self)
|
|||
{
|
||||
edict_t *ent;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* commander sounds */
|
||||
if (self->mass == 400)
|
||||
{
|
||||
|
@ -384,7 +434,7 @@ medic_sight(edict_t *self, edict_t *other /* unused */)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t medic_frames_stand[] = {
|
||||
static mframe_t medic_frames_stand[] = {
|
||||
{ai_stand, 0, medic_idle},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -477,7 +527,8 @@ mframe_t medic_frames_stand[] = {
|
|||
{ai_stand, 0, NULL},
|
||||
};
|
||||
|
||||
mmove_t medic_move_stand = {
|
||||
mmove_t medic_move_stand =
|
||||
{
|
||||
FRAME_wait1,
|
||||
FRAME_wait90,
|
||||
medic_frames_stand,
|
||||
|
@ -495,22 +546,23 @@ medic_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &medic_move_stand;
|
||||
}
|
||||
|
||||
mframe_t medic_frames_walk[] = {
|
||||
static mframe_t medic_frames_walk[] = {
|
||||
{ai_walk, 6.2, NULL},
|
||||
{ai_walk, 18.1, NULL},
|
||||
{ai_walk, 18.1, medic_footstep},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, 10, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, 11, NULL},
|
||||
{ai_walk, 11.6, NULL},
|
||||
{ai_walk, 11.6, medic_footstep},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 9.9, NULL},
|
||||
{ai_walk, 14, NULL},
|
||||
{ai_walk, 9.3, NULL}
|
||||
};
|
||||
|
||||
mmove_t medic_move_walk = {
|
||||
mmove_t medic_move_walk =
|
||||
{
|
||||
FRAME_walk1,
|
||||
FRAME_walk12,
|
||||
medic_frames_walk,
|
||||
|
@ -528,19 +580,20 @@ medic_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &medic_move_walk;
|
||||
}
|
||||
|
||||
mframe_t medic_frames_run[] = {
|
||||
{ai_run, 18, NULL},
|
||||
static mframe_t medic_frames_run[] = {
|
||||
{ai_run, 18, medic_footstep},
|
||||
{ai_run, 22.5, NULL},
|
||||
{ai_run, 25.4, monster_done_dodge},
|
||||
{ai_run, 23.4, NULL},
|
||||
{ai_run, 24, NULL},
|
||||
{ai_run, 24, medic_footstep},
|
||||
{ai_run, 35.6, NULL}
|
||||
};
|
||||
|
||||
mmove_t medic_move_run = {
|
||||
mmove_t medic_move_run =
|
||||
{
|
||||
FRAME_run1,
|
||||
FRAME_run6,
|
||||
medic_frames_run,
|
||||
FRAME_run6,
|
||||
medic_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -581,7 +634,7 @@ medic_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t medic_frames_pain1[] = {
|
||||
static mframe_t medic_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -592,14 +645,19 @@ mframe_t medic_frames_pain1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t medic_move_pain1 = {
|
||||
mmove_t medic_move_pain1 =
|
||||
{
|
||||
FRAME_paina1,
|
||||
FRAME_paina8,
|
||||
FRAME_paina8,
|
||||
medic_frames_pain1,
|
||||
medic_run
|
||||
};
|
||||
|
||||
mframe_t medic_frames_pain2[] = {
|
||||
static mframe_t medic_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, medic_footstep},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -610,14 +668,11 @@ mframe_t medic_frames_pain2[] = {
|
|||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
{ai_move, 0, medic_footstep}
|
||||
};
|
||||
|
||||
mmove_t medic_move_pain2 = {
|
||||
mmove_t medic_move_pain2 =
|
||||
{
|
||||
FRAME_painb1,
|
||||
FRAME_painb15,
|
||||
medic_frames_pain2,
|
||||
|
@ -625,7 +680,8 @@ mmove_t medic_move_pain2 = {
|
|||
};
|
||||
|
||||
void
|
||||
medic_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
medic_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick, int damage /* unused */)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -783,7 +839,7 @@ medic_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t medic_frames_death[] = {
|
||||
static mframe_t medic_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -816,7 +872,8 @@ mframe_t medic_frames_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t medic_move_death = {
|
||||
mmove_t medic_move_death =
|
||||
{
|
||||
FRAME_death1,
|
||||
FRAME_death30,
|
||||
medic_frames_death,
|
||||
|
@ -824,8 +881,9 @@ mmove_t medic_move_death = {
|
|||
};
|
||||
|
||||
void
|
||||
medic_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
medic_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -841,15 +899,18 @@ medic_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -875,7 +936,7 @@ medic_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
self->monsterinfo.currentmove = &medic_move_death;
|
||||
}
|
||||
|
||||
mframe_t medic_frames_duck[] = {
|
||||
static mframe_t medic_frames_duck[] = {
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -1, monster_duck_down},
|
||||
|
@ -894,14 +955,15 @@ mframe_t medic_frames_duck[] = {
|
|||
{ai_move, -1, NULL}
|
||||
};
|
||||
|
||||
mmove_t medic_move_duck = {
|
||||
mmove_t medic_move_duck =
|
||||
{
|
||||
FRAME_duck1,
|
||||
FRAME_duck16,
|
||||
medic_frames_duck,
|
||||
medic_run
|
||||
};
|
||||
|
||||
mframe_t medic_frames_attackHyperBlaster[] = {
|
||||
static mframe_t medic_frames_attackHyperBlaster[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -920,7 +982,8 @@ mframe_t medic_frames_attackHyperBlaster[] = {
|
|||
{ai_charge, 0, medic_fire_blaster}
|
||||
};
|
||||
|
||||
mmove_t medic_move_attackHyperBlaster = {
|
||||
mmove_t medic_move_attackHyperBlaster =
|
||||
{
|
||||
FRAME_attack15,
|
||||
FRAME_attack30,
|
||||
medic_frames_attackHyperBlaster,
|
||||
|
@ -944,7 +1007,7 @@ medic_continue(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t medic_frames_attackBlaster[] = {
|
||||
static mframe_t medic_frames_attackBlaster[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
|
@ -1227,7 +1290,7 @@ medic_hook_retract(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t medic_frames_attackCable[] = {
|
||||
static mframe_t medic_frames_attackCable[] = {
|
||||
{ai_charge, 2, NULL}, /* 33 */
|
||||
{ai_charge, 3, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
|
@ -1235,7 +1298,7 @@ mframe_t medic_frames_attackCable[] = {
|
|||
{ai_charge, -4.7, NULL}, /* 37 */
|
||||
{ai_charge, -5, NULL},
|
||||
{ai_charge, -6, NULL},
|
||||
{ai_charge, -4, NULL}, /* 40 */
|
||||
{ai_charge, -4, medic_footstep}, /* 40 */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_move, 0, medic_hook_launch}, /* 42 */
|
||||
{ai_move, 0, medic_cable_attack}, /* 43 */
|
||||
|
@ -1249,16 +1312,17 @@ mframe_t medic_frames_attackCable[] = {
|
|||
{ai_move, 0, medic_cable_attack}, /* 51 */
|
||||
{ai_move, 0, medic_hook_retract}, /* 52 */
|
||||
{ai_move, -1.5, NULL},
|
||||
{ai_move, -1.2, NULL},
|
||||
{ai_move, -1.2, medic_footstep},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, 0.3, NULL},
|
||||
{ai_move, 0.7, NULL},
|
||||
{ai_move, 1.2, NULL},
|
||||
{ai_move, 1.3, NULL} /* 60 */
|
||||
|
||||
};
|
||||
mmove_t medic_move_attackCable = {
|
||||
|
||||
mmove_t medic_move_attackCable =
|
||||
{
|
||||
FRAME_attack33,
|
||||
FRAME_attack60,
|
||||
medic_frames_attackCable,
|
||||
|
@ -1606,7 +1670,7 @@ medic_finish_spawn(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t medic_frames_callReinforcements[] = {
|
||||
static mframe_t medic_frames_callReinforcements[] = {
|
||||
{ai_charge, 2, NULL}, /* 33 */
|
||||
{ai_charge, 3, NULL},
|
||||
{ai_charge, 5, NULL},
|
||||
|
@ -1893,6 +1957,11 @@ SP_monster_medic(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
|
||||
self->movetype = MOVETYPE_STEP;
|
||||
self->solid = SOLID_BBOX;
|
||||
self->s.modelindex = gi.modelindex("models/monsters/medic/tris.md2");
|
||||
|
|
|
@ -83,7 +83,7 @@ mutant_swing(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_swing, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_stand[] = {
|
||||
static mframe_t mutant_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -174,7 +174,7 @@ mutant_idle_loop(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_idle[] = {
|
||||
static mframe_t mutant_frames_idle[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -209,7 +209,7 @@ mutant_idle(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_walk[] = {
|
||||
static mframe_t mutant_frames_walk[] = {
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
|
@ -242,7 +242,7 @@ mutant_walk_loop(edict_t *self)
|
|||
self->monsterinfo.currentmove = &mutant_move_walk;
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_start_walk[] = {
|
||||
static mframe_t mutant_frames_start_walk[] = {
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, -2, NULL},
|
||||
|
@ -267,7 +267,7 @@ mutant_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &mutant_move_start_walk;
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_run[] = {
|
||||
static mframe_t mutant_frames_run[] = {
|
||||
{ai_run, 40, NULL},
|
||||
{ai_run, 40, mutant_step},
|
||||
{ai_run, 24, NULL},
|
||||
|
@ -364,7 +364,7 @@ mutant_check_refire(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_attack[] = {
|
||||
static mframe_t mutant_frames_attack[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, mutant_hit_left},
|
||||
|
@ -485,7 +485,7 @@ mutant_check_landing(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_jump[] = {
|
||||
static mframe_t mutant_frames_jump[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 17, NULL},
|
||||
{ai_charge, 15, mutant_jump_takeoff},
|
||||
|
@ -600,7 +600,7 @@ mutant_checkattack(edict_t *self)
|
|||
return false;
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_pain1[] = {
|
||||
static mframe_t mutant_frames_pain1[] = {
|
||||
{ai_move, 4, NULL},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, -8, NULL},
|
||||
|
@ -615,7 +615,7 @@ mmove_t mutant_move_pain1 = {
|
|||
mutant_run
|
||||
};
|
||||
|
||||
mframe_t mutant_frames_pain2[] = {
|
||||
static mframe_t mutant_frames_pain2[] = {
|
||||
{ai_move, -24, NULL},
|
||||
{ai_move, 11, NULL},
|
||||
{ai_move, 5, NULL},
|
||||
|
@ -631,7 +631,7 @@ mmove_t mutant_move_pain2 = {
|
|||
mutant_run
|
||||
};
|
||||
|
||||
mframe_t mutant_frames_pain3[] = {
|
||||
static mframe_t mutant_frames_pain3[] = {
|
||||
{ai_move, -22, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
|
@ -715,7 +715,7 @@ mutant_dead(edict_t *self)
|
|||
M_FlyCheck(self);
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_death1[] = {
|
||||
static mframe_t mutant_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -734,7 +734,7 @@ mmove_t mutant_move_death1 = {
|
|||
mutant_dead
|
||||
};
|
||||
|
||||
mframe_t mutant_frames_death2[] = {
|
||||
static mframe_t mutant_frames_death2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -841,13 +841,13 @@ mutant_jump_wait_land(edict_t *self)
|
|||
{
|
||||
self->monsterinfo.nextframe = self->s.frame;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
self->monsterinfo.nextframe = self->s.frame + 1;
|
||||
}
|
||||
}
|
||||
|
||||
mframe_t mutant_frames_jump_up[] = {
|
||||
static mframe_t mutant_frames_jump_up[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -8, mutant_jump_up},
|
||||
{ai_move, 0, mutant_jump_wait_land},
|
||||
|
@ -862,7 +862,7 @@ mmove_t mutant_move_jump_up = {
|
|||
mutant_run
|
||||
};
|
||||
|
||||
mframe_t mutant_frames_jump_down[] = {
|
||||
static mframe_t mutant_frames_jump_down[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, mutant_jump_down},
|
||||
{ai_move, 0, mutant_jump_wait_land},
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Parasite.
|
||||
*
|
||||
|
@ -52,7 +71,7 @@ parasite_reel_in(edict_t *self)
|
|||
}
|
||||
|
||||
void
|
||||
parasite_sight(edict_t *self, edict_t *other)
|
||||
parasite_sight(edict_t *self, edict_t *other /* unused */)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -73,6 +92,15 @@ parasite_tap(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_tap, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
parasite_footstep(edict_t *self)
|
||||
{
|
||||
if (g_monsterfootsteps->value)
|
||||
{
|
||||
parasite_tap(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parasite_scratch(edict_t *self)
|
||||
{
|
||||
|
@ -95,21 +123,22 @@ parasite_search(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_search, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_start_fidget[] = {
|
||||
static mframe_t parasite_frames_start_fidget[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_start_fidget = {
|
||||
mmove_t parasite_move_start_fidget =
|
||||
{
|
||||
FRAME_stand18,
|
||||
FRAME_stand21,
|
||||
FRAME_stand21,
|
||||
parasite_frames_start_fidget,
|
||||
parasite_do_fidget
|
||||
parasite_do_fidget
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_fidget[] = {
|
||||
static mframe_t parasite_frames_fidget[] = {
|
||||
{ai_stand, 0, parasite_scratch},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -118,14 +147,15 @@ mframe_t parasite_frames_fidget[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_fidget = {
|
||||
mmove_t parasite_move_fidget =
|
||||
{
|
||||
FRAME_stand22,
|
||||
FRAME_stand27,
|
||||
parasite_frames_fidget,
|
||||
parasite_refidget
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_end_fidget[] = {
|
||||
static mframe_t parasite_frames_end_fidget[] = {
|
||||
{ai_stand, 0, parasite_scratch},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -136,7 +166,8 @@ mframe_t parasite_frames_end_fidget[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_end_fidget = {
|
||||
mmove_t parasite_move_end_fidget =
|
||||
{
|
||||
FRAME_stand28,
|
||||
FRAME_stand35,
|
||||
parasite_frames_end_fidget,
|
||||
|
@ -194,7 +225,7 @@ parasite_idle(edict_t *self)
|
|||
self->monsterinfo.currentmove = ¶site_move_start_fidget;
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_stand[] = {
|
||||
static mframe_t parasite_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, parasite_tap},
|
||||
|
@ -214,9 +245,10 @@ mframe_t parasite_frames_stand[] = {
|
|||
{ai_stand, 0, parasite_tap}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_stand = {
|
||||
mmove_t parasite_move_stand =
|
||||
{
|
||||
FRAME_stand01,
|
||||
FRAME_stand17,
|
||||
FRAME_stand17,
|
||||
parasite_frames_stand,
|
||||
parasite_stand
|
||||
};
|
||||
|
@ -232,49 +264,52 @@ parasite_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = ¶site_move_stand;
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_run[] = {
|
||||
static mframe_t parasite_frames_run[] = {
|
||||
{ai_run, 30, NULL},
|
||||
{ai_run, 30, NULL},
|
||||
{ai_run, 22, NULL},
|
||||
{ai_run, 19, NULL},
|
||||
{ai_run, 22, parasite_footstep},
|
||||
{ai_run, 19, parasite_footstep},
|
||||
{ai_run, 24, NULL},
|
||||
{ai_run, 28, NULL},
|
||||
{ai_run, 28, parasite_footstep},
|
||||
{ai_run, 25, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_run = {
|
||||
mmove_t parasite_move_run =
|
||||
{
|
||||
FRAME_run03,
|
||||
FRAME_run09,
|
||||
parasite_frames_run,
|
||||
NULL
|
||||
FRAME_run09,
|
||||
parasite_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_start_run[] = {
|
||||
static mframe_t parasite_frames_start_run[] = {
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 30, NULL},
|
||||
};
|
||||
|
||||
mmove_t parasite_move_start_run = {
|
||||
mmove_t parasite_move_start_run =
|
||||
{
|
||||
FRAME_run01,
|
||||
FRAME_run02,
|
||||
parasite_frames_start_run,
|
||||
parasite_run
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_stop_run[] = {
|
||||
static mframe_t parasite_frames_stop_run[] = {
|
||||
{ai_run, 20, NULL},
|
||||
{ai_run, 20, NULL},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 12, parasite_footstep},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_stop_run = {
|
||||
mmove_t parasite_move_stop_run =
|
||||
{
|
||||
FRAME_run10,
|
||||
FRAME_run15,
|
||||
parasite_frames_stop_run,
|
||||
NULL
|
||||
FRAME_run15,
|
||||
parasite_frames_stop_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -313,45 +348,48 @@ parasite_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_walk[] = {
|
||||
static mframe_t parasite_frames_walk[] = {
|
||||
{ai_walk, 30, NULL},
|
||||
{ai_walk, 30, NULL},
|
||||
{ai_walk, 22, NULL},
|
||||
{ai_walk, 22, parasite_footstep},
|
||||
{ai_walk, 19, NULL},
|
||||
{ai_walk, 24, NULL},
|
||||
{ai_walk, 28, NULL},
|
||||
{ai_walk, 24, parasite_footstep},
|
||||
{ai_walk, 28, parasite_footstep},
|
||||
{ai_walk, 25, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_walk = {
|
||||
mmove_t parasite_move_walk =
|
||||
{
|
||||
FRAME_run03,
|
||||
FRAME_run09,
|
||||
parasite_frames_walk,
|
||||
parasite_walk
|
||||
FRAME_run09,
|
||||
parasite_frames_walk,
|
||||
parasite_walk
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_start_walk[] = {
|
||||
static mframe_t parasite_frames_start_walk[] = {
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 30, parasite_walk}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_start_walk = {
|
||||
mmove_t parasite_move_start_walk =
|
||||
{
|
||||
FRAME_run01,
|
||||
FRAME_run02,
|
||||
FRAME_run02,
|
||||
parasite_frames_start_walk,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_stop_walk[] = {
|
||||
static mframe_t parasite_frames_stop_walk[] = {
|
||||
{ai_walk, 20, NULL},
|
||||
{ai_walk, 20, NULL},
|
||||
{ai_walk, 12, NULL},
|
||||
{ai_walk, 12, parasite_footstep},
|
||||
{ai_walk, 10, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_stop_walk = {
|
||||
mmove_t parasite_move_stop_walk =
|
||||
{
|
||||
FRAME_run10,
|
||||
FRAME_run15,
|
||||
parasite_frames_stop_walk,
|
||||
|
@ -380,7 +418,7 @@ parasite_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = ¶site_move_walk;
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_pain1[] = {
|
||||
static mframe_t parasite_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -394,15 +432,17 @@ mframe_t parasite_frames_pain1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_pain1 = {
|
||||
mmove_t parasite_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain111,
|
||||
FRAME_pain111,
|
||||
parasite_frames_pain1,
|
||||
parasite_start_run
|
||||
};
|
||||
|
||||
void
|
||||
parasite_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
parasite_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage /* unused */)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
|
@ -548,7 +588,7 @@ parasite_drain_attack(edict_t *self)
|
|||
damage, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN);
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_drain[] = {
|
||||
static mframe_t parasite_frames_drain[] = {
|
||||
{ai_charge, 0, parasite_launch},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 15, parasite_drain_attack}, /* Target hits */
|
||||
|
@ -569,14 +609,15 @@ mframe_t parasite_frames_drain[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_drain = {
|
||||
mmove_t parasite_move_drain =
|
||||
{
|
||||
FRAME_drain01,
|
||||
FRAME_drain18,
|
||||
parasite_frames_drain,
|
||||
parasite_start_run
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_break[] = {
|
||||
static mframe_t parasite_frames_break[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, -3, NULL},
|
||||
{ai_charge, 1, NULL},
|
||||
|
@ -598,12 +639,12 @@ mframe_t parasite_frames_break[] = {
|
|||
{ai_charge, 0, NULL},
|
||||
{ai_charge, -18, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}, /* airborne */
|
||||
{ai_charge, 0, NULL}, /* airborne */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* airborne */
|
||||
{ai_charge, 0, NULL}, /* airborne */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 0, NULL}, /* slides */
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 11, NULL},
|
||||
{ai_charge, -2, NULL},
|
||||
|
@ -611,10 +652,11 @@ mframe_t parasite_frames_break[] = {
|
|||
{ai_charge, 1, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_break = {
|
||||
mmove_t parasite_move_break =
|
||||
{
|
||||
FRAME_break01,
|
||||
FRAME_break32,
|
||||
parasite_frames_break,
|
||||
FRAME_break32,
|
||||
parasite_frames_break,
|
||||
parasite_start_run
|
||||
};
|
||||
|
||||
|
@ -686,7 +728,7 @@ parasite_jump_wait_land(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_jump_up[] = {
|
||||
static mframe_t parasite_frames_jump_up[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -8, NULL},
|
||||
|
@ -704,7 +746,7 @@ mmove_t parasite_move_jump_up = {
|
|||
parasite_run
|
||||
};
|
||||
|
||||
mframe_t parasite_frames_jump_down[] = {
|
||||
static mframe_t parasite_frames_jump_down[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -877,7 +919,7 @@ parasite_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_death[] = {
|
||||
static mframe_t parasite_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -887,7 +929,8 @@ mframe_t parasite_frames_death[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t parasite_move_death = {
|
||||
mmove_t parasite_move_death =
|
||||
{
|
||||
FRAME_death101,
|
||||
FRAME_death107,
|
||||
parasite_frames_death,
|
||||
|
@ -895,12 +938,13 @@ mmove_t parasite_move_death = {
|
|||
};
|
||||
|
||||
void
|
||||
parasite_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unsued */)
|
||||
parasite_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -912,15 +956,18 @@ parasite_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /
|
|||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/bone/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/* =======================================================================
|
||||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Soldier aka "Guard". This is the most complex enemy in Quake 2, since
|
||||
* it uses all AI features (dodging, sight, crouching, etc) and comes
|
||||
|
@ -21,6 +40,10 @@ static int sound_death_light;
|
|||
static int sound_death;
|
||||
static int sound_death_ss;
|
||||
static int sound_cock;
|
||||
static int sound_step;
|
||||
static int sound_step2;
|
||||
static int sound_step3;
|
||||
static int sound_step4;
|
||||
|
||||
void soldier_duck_up(edict_t *self);
|
||||
void soldier_stand(edict_t *self);
|
||||
|
@ -28,6 +51,42 @@ void soldier_run(edict_t *self);
|
|||
void soldier_fire(edict_t *self, int);
|
||||
void soldier_blind(edict_t *self);
|
||||
|
||||
void
|
||||
soldier_footstep(edict_t *self)
|
||||
{
|
||||
if (!g_monsterfootsteps->value)
|
||||
return;
|
||||
|
||||
// Lazy loading for savegame compatibility.
|
||||
if (sound_step == 0 || sound_step2 == 0 || sound_step3 == 0 || sound_step4 == 0)
|
||||
{
|
||||
sound_step = gi.soundindex("player/step1.wav");
|
||||
sound_step2 = gi.soundindex("player/step2.wav");
|
||||
sound_step3 = gi.soundindex("player/step3.wav");
|
||||
sound_step4 = gi.soundindex("player/step4.wav");
|
||||
}
|
||||
|
||||
int i;
|
||||
i = randk() % 4;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step3, 1, ATTN_NORM, 0);
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, sound_step4, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
soldier_start_charge(edict_t *self)
|
||||
{
|
||||
|
@ -50,6 +109,7 @@ soldier_stop_charge(edict_t *self)
|
|||
self->monsterinfo.aiflags &= ~AI_CHARGING;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
soldier_idle(edict_t *self)
|
||||
{
|
||||
|
@ -82,7 +142,7 @@ soldier_cock(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_stand1[] = {
|
||||
static mframe_t soldier_frames_stand1[] = {
|
||||
{ai_stand, 0, soldier_idle},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -117,14 +177,15 @@ mframe_t soldier_frames_stand1[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_stand1 = {
|
||||
mmove_t soldier_move_stand1 =
|
||||
{
|
||||
FRAME_stand101,
|
||||
FRAME_stand130,
|
||||
soldier_frames_stand1,
|
||||
soldier_stand
|
||||
soldier_frames_stand1,
|
||||
soldier_stand
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_stand3[] = {
|
||||
static mframe_t soldier_frames_stand3[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -169,7 +230,8 @@ mframe_t soldier_frames_stand3[] = {
|
|||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_stand3 = {
|
||||
mmove_t soldier_move_stand3 =
|
||||
{
|
||||
FRAME_stand301,
|
||||
FRAME_stand339,
|
||||
soldier_frames_stand3,
|
||||
|
@ -209,16 +271,16 @@ soldier_walk1_random(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_walk1[] = {
|
||||
static mframe_t soldier_frames_walk1[] = {
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 2, soldier_footstep},
|
||||
{ai_walk, 2, NULL},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 3, soldier_footstep},
|
||||
{ai_walk, -1, soldier_walk1_random},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
|
@ -245,19 +307,20 @@ mframe_t soldier_frames_walk1[] = {
|
|||
{ai_walk, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_walk1 = {
|
||||
mmove_t soldier_move_walk1 =
|
||||
{
|
||||
FRAME_walk101,
|
||||
FRAME_walk133,
|
||||
soldier_frames_walk1,
|
||||
NULL
|
||||
FRAME_walk133,
|
||||
soldier_frames_walk1,
|
||||
NULL
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_walk2[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
static mframe_t soldier_frames_walk2[] = {
|
||||
{ai_walk, 4, soldier_footstep},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 9, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 5, soldier_footstep},
|
||||
{ai_walk, 1, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 7, NULL},
|
||||
|
@ -265,10 +328,11 @@ mframe_t soldier_frames_walk2[] = {
|
|||
{ai_walk, 7, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_walk2 = {
|
||||
mmove_t soldier_move_walk2 =
|
||||
{
|
||||
FRAME_walk209,
|
||||
FRAME_walk218,
|
||||
soldier_frames_walk2,
|
||||
soldier_frames_walk2,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -290,12 +354,13 @@ soldier_walk(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_start_run[] = {
|
||||
static mframe_t soldier_frames_start_run[] = {
|
||||
{ai_run, 7, NULL},
|
||||
{ai_run, 5, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_start_run = {
|
||||
mmove_t soldier_move_start_run =
|
||||
{
|
||||
FRAME_run01,
|
||||
FRAME_run02,
|
||||
soldier_frames_start_run,
|
||||
|
@ -316,19 +381,20 @@ soldier_fire_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_run[] = {
|
||||
static mframe_t soldier_frames_run[] = {
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 11, soldier_footstep},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 16, NULL},
|
||||
{ai_run, 10, NULL},
|
||||
{ai_run, 10, soldier_footstep},
|
||||
{ai_run, 15, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_run = {
|
||||
mmove_t soldier_move_run =
|
||||
{
|
||||
FRAME_run03,
|
||||
FRAME_run08,
|
||||
soldier_frames_run,
|
||||
FRAME_run08,
|
||||
soldier_frames_run,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -360,7 +426,7 @@ soldier_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_pain1[] = {
|
||||
static mframe_t soldier_frames_pain1[] = {
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, 4, NULL},
|
||||
{ai_move, 1, NULL},
|
||||
|
@ -368,14 +434,15 @@ mframe_t soldier_frames_pain1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_pain1 = {
|
||||
mmove_t soldier_move_pain1 =
|
||||
{
|
||||
FRAME_pain101,
|
||||
FRAME_pain105,
|
||||
soldier_frames_pain1,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_pain2[] = {
|
||||
static mframe_t soldier_frames_pain2[] = {
|
||||
{ai_move, -13, NULL},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
|
@ -385,17 +452,18 @@ mframe_t soldier_frames_pain2[] = {
|
|||
{ai_move, 2, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_pain2 = {
|
||||
mmove_t soldier_move_pain2 =
|
||||
{
|
||||
FRAME_pain201,
|
||||
FRAME_pain207,
|
||||
FRAME_pain207,
|
||||
soldier_frames_pain2,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_pain3[] = {
|
||||
static mframe_t soldier_frames_pain3[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, 10, NULL},
|
||||
{ai_move, -4, NULL},
|
||||
{ai_move, -4, soldier_footstep},
|
||||
{ai_move, -1, NULL},
|
||||
{ai_move, -3, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -410,17 +478,18 @@ mframe_t soldier_frames_pain3[] = {
|
|||
{ai_move, 2, NULL},
|
||||
{ai_move, 4, NULL},
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 2, NULL}
|
||||
{ai_move, 2, soldier_footstep}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_pain3 = {
|
||||
mmove_t soldier_move_pain3 =
|
||||
{
|
||||
FRAME_pain301,
|
||||
FRAME_pain318,
|
||||
soldier_frames_pain3,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_pain4[] = {
|
||||
static mframe_t soldier_frames_pain4[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -440,15 +509,17 @@ mframe_t soldier_frames_pain4[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_pain4 = {
|
||||
mmove_t soldier_move_pain4 =
|
||||
{
|
||||
FRAME_pain401,
|
||||
FRAME_pain417,
|
||||
soldier_frames_pain4,
|
||||
FRAME_pain417,
|
||||
soldier_frames_pain4,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
void
|
||||
soldier_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
||||
soldier_pain(edict_t *self, edict_t *other /* unused */,
|
||||
float kick /* unused */, int damage /* unused */)
|
||||
{
|
||||
float r;
|
||||
int n;
|
||||
|
@ -473,8 +544,8 @@ soldier_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
{
|
||||
if ((self->velocity[2] > 100) &&
|
||||
((self->monsterinfo.currentmove == &soldier_move_pain1) ||
|
||||
(self->monsterinfo.currentmove == &soldier_move_pain2) ||
|
||||
(self->monsterinfo.currentmove == &soldier_move_pain3)))
|
||||
(self->monsterinfo.currentmove == &soldier_move_pain2) ||
|
||||
(self->monsterinfo.currentmove == &soldier_move_pain3)))
|
||||
{
|
||||
/* clear duck flag */
|
||||
if (self->monsterinfo.aiflags & AI_DUCKED)
|
||||
|
@ -545,20 +616,40 @@ soldier_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
|
|||
}
|
||||
|
||||
static int blaster_flash[] =
|
||||
{MZ2_SOLDIER_BLASTER_1, MZ2_SOLDIER_BLASTER_2, MZ2_SOLDIER_BLASTER_3,
|
||||
MZ2_SOLDIER_BLASTER_4, MZ2_SOLDIER_BLASTER_5, MZ2_SOLDIER_BLASTER_6,
|
||||
MZ2_SOLDIER_BLASTER_7, MZ2_SOLDIER_BLASTER_8};
|
||||
{
|
||||
MZ2_SOLDIER_BLASTER_1,
|
||||
MZ2_SOLDIER_BLASTER_2,
|
||||
MZ2_SOLDIER_BLASTER_3,
|
||||
MZ2_SOLDIER_BLASTER_4,
|
||||
MZ2_SOLDIER_BLASTER_5,
|
||||
MZ2_SOLDIER_BLASTER_6,
|
||||
MZ2_SOLDIER_BLASTER_7,
|
||||
MZ2_SOLDIER_BLASTER_8
|
||||
};
|
||||
|
||||
static int shotgun_flash[] =
|
||||
{MZ2_SOLDIER_SHOTGUN_1, MZ2_SOLDIER_SHOTGUN_2, MZ2_SOLDIER_SHOTGUN_3,
|
||||
MZ2_SOLDIER_SHOTGUN_4, MZ2_SOLDIER_SHOTGUN_5, MZ2_SOLDIER_SHOTGUN_6,
|
||||
MZ2_SOLDIER_SHOTGUN_7, MZ2_SOLDIER_SHOTGUN_8};
|
||||
{
|
||||
MZ2_SOLDIER_SHOTGUN_1,
|
||||
MZ2_SOLDIER_SHOTGUN_2,
|
||||
MZ2_SOLDIER_SHOTGUN_3,
|
||||
MZ2_SOLDIER_SHOTGUN_4,
|
||||
MZ2_SOLDIER_SHOTGUN_5,
|
||||
MZ2_SOLDIER_SHOTGUN_6,
|
||||
MZ2_SOLDIER_SHOTGUN_7,
|
||||
MZ2_SOLDIER_SHOTGUN_8
|
||||
};
|
||||
|
||||
static int machinegun_flash[] =
|
||||
{MZ2_SOLDIER_MACHINEGUN_1, MZ2_SOLDIER_MACHINEGUN_2, MZ2_SOLDIER_MACHINEGUN_3,
|
||||
MZ2_SOLDIER_MACHINEGUN_4, MZ2_SOLDIER_MACHINEGUN_5,
|
||||
MZ2_SOLDIER_MACHINEGUN_6, MZ2_SOLDIER_MACHINEGUN_7,
|
||||
MZ2_SOLDIER_MACHINEGUN_8};
|
||||
{
|
||||
MZ2_SOLDIER_MACHINEGUN_1,
|
||||
MZ2_SOLDIER_MACHINEGUN_2,
|
||||
MZ2_SOLDIER_MACHINEGUN_3,
|
||||
MZ2_SOLDIER_MACHINEGUN_4,
|
||||
MZ2_SOLDIER_MACHINEGUN_5,
|
||||
MZ2_SOLDIER_MACHINEGUN_6,
|
||||
MZ2_SOLDIER_MACHINEGUN_7,
|
||||
MZ2_SOLDIER_MACHINEGUN_8
|
||||
};
|
||||
|
||||
void
|
||||
soldier_fire(edict_t *self, int in_flash_number)
|
||||
|
@ -779,7 +870,7 @@ soldier_attack1_refire2(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_attack1[] = {
|
||||
static mframe_t soldier_frames_attack1[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, soldier_fire1},
|
||||
|
@ -794,10 +885,11 @@ mframe_t soldier_frames_attack1[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_attack1 = {
|
||||
mmove_t soldier_move_attack1 =
|
||||
{
|
||||
FRAME_attak101,
|
||||
FRAME_attak112,
|
||||
soldier_frames_attack1,
|
||||
FRAME_attak112,
|
||||
soldier_frames_attack1,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
|
@ -835,7 +927,8 @@ soldier_attack2_refire1(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (((skill->value == SKILL_HARDPLUS) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
|
||||
if (((skill->value == SKILL_HARDPLUS) &&
|
||||
(random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
|
||||
{
|
||||
self->monsterinfo.nextframe = FRAME_attak204;
|
||||
}
|
||||
|
@ -868,13 +961,14 @@ soldier_attack2_refire2(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (((skill->value == SKILL_HARDPLUS) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
|
||||
if (((skill->value == SKILL_HARDPLUS) &&
|
||||
(random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
|
||||
{
|
||||
self->monsterinfo.nextframe = FRAME_attak204;
|
||||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_attack2[] = {
|
||||
static mframe_t soldier_frames_attack2[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -895,7 +989,8 @@ mframe_t soldier_frames_attack2[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_attack2 = {
|
||||
mmove_t soldier_move_attack2 =
|
||||
{
|
||||
FRAME_attak201,
|
||||
FRAME_attak218,
|
||||
soldier_frames_attack2,
|
||||
|
@ -928,7 +1023,7 @@ soldier_attack3_refire(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_attack3[] = {
|
||||
static mframe_t soldier_frames_attack3[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, soldier_fire3},
|
||||
|
@ -940,11 +1035,12 @@ mframe_t soldier_frames_attack3[] = {
|
|||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_attack3 = {
|
||||
mmove_t soldier_move_attack3 =
|
||||
{
|
||||
FRAME_attak301,
|
||||
FRAME_attak309,
|
||||
soldier_frames_attack3,
|
||||
soldier_run
|
||||
FRAME_attak309,
|
||||
soldier_frames_attack3,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -958,16 +1054,17 @@ soldier_fire4(edict_t *self)
|
|||
soldier_fire(self, 3);
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_attack4[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
static mframe_t soldier_frames_attack4[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, soldier_footstep},
|
||||
{ai_charge, 0, soldier_fire4},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
{ai_charge, 0, soldier_footstep}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_attack4 = {
|
||||
mmove_t soldier_move_attack4 =
|
||||
{
|
||||
FRAME_attak401,
|
||||
FRAME_attak406,
|
||||
soldier_frames_attack4,
|
||||
|
@ -1018,11 +1115,11 @@ soldier_attack6_refire(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_attack6[] = {
|
||||
static mframe_t soldier_frames_attack6[] = {
|
||||
{ai_run, 10, soldier_start_charge},
|
||||
{ai_run, 4, NULL},
|
||||
{ai_run, 12, soldier_fire8},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 11, soldier_footstep},
|
||||
{ai_run, 13, monster_done_dodge},
|
||||
{ai_run, 18, NULL},
|
||||
{ai_run, 15, NULL},
|
||||
|
@ -1035,11 +1132,12 @@ mframe_t soldier_frames_attack6[] = {
|
|||
{ai_run, 17, soldier_attack6_refire}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_attack6 = {
|
||||
mmove_t soldier_move_attack6 =
|
||||
{
|
||||
FRAME_runs01,
|
||||
FRAME_runs14,
|
||||
soldier_frames_attack6,
|
||||
soldier_run
|
||||
FRAME_runs14,
|
||||
soldier_frames_attack6,
|
||||
soldier_run
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1152,7 +1250,7 @@ soldier_sight(edict_t *self, edict_t *other /* unused */)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_duck[] = {
|
||||
static mframe_t soldier_frames_duck[] = {
|
||||
{ai_move, 5, monster_duck_down},
|
||||
{ai_move, -1, monster_duck_hold},
|
||||
{ai_move, 1, NULL},
|
||||
|
@ -1160,7 +1258,8 @@ mframe_t soldier_frames_duck[] = {
|
|||
{ai_move, 5, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_duck = {
|
||||
mmove_t soldier_move_duck =
|
||||
{
|
||||
FRAME_duck01,
|
||||
FRAME_duck05,
|
||||
soldier_frames_duck,
|
||||
|
@ -1268,7 +1367,7 @@ soldier_dead2(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_death1[] = {
|
||||
static mframe_t soldier_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -10, NULL},
|
||||
{ai_move, -10, NULL},
|
||||
|
@ -1310,14 +1409,15 @@ mframe_t soldier_frames_death1[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death1 = {
|
||||
mmove_t soldier_move_death1 =
|
||||
{
|
||||
FRAME_death101,
|
||||
FRAME_death136,
|
||||
soldier_frames_death1,
|
||||
soldier_dead
|
||||
FRAME_death136,
|
||||
soldier_frames_death1,
|
||||
soldier_dead
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_death2[] = {
|
||||
static mframe_t soldier_frames_death2[] = {
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
|
@ -1358,14 +1458,15 @@ mframe_t soldier_frames_death2[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death2 = {
|
||||
mmove_t soldier_move_death2 =
|
||||
{
|
||||
FRAME_death201,
|
||||
FRAME_death235,
|
||||
FRAME_death235,
|
||||
soldier_frames_death2,
|
||||
soldier_dead
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_death3[] = {
|
||||
static mframe_t soldier_frames_death3[] = {
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
|
@ -1417,14 +1518,15 @@ mframe_t soldier_frames_death3[] = {
|
|||
{ai_move, 0, NULL},
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death3 = {
|
||||
mmove_t soldier_move_death3 =
|
||||
{
|
||||
FRAME_death301,
|
||||
FRAME_death345,
|
||||
soldier_frames_death3,
|
||||
soldier_dead
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_death4[] = {
|
||||
static mframe_t soldier_frames_death4[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1485,14 +1587,15 @@ mframe_t soldier_frames_death4[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death4 = {
|
||||
mmove_t soldier_move_death4 =
|
||||
{
|
||||
FRAME_death401,
|
||||
FRAME_death453,
|
||||
soldier_frames_death4,
|
||||
soldier_dead2
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_death5[] = {
|
||||
static mframe_t soldier_frames_death5[] = {
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
|
@ -1521,14 +1624,15 @@ mframe_t soldier_frames_death5[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death5 = {
|
||||
mmove_t soldier_move_death5 =
|
||||
{
|
||||
FRAME_death501,
|
||||
FRAME_death524,
|
||||
soldier_frames_death5,
|
||||
soldier_dead
|
||||
};
|
||||
|
||||
mframe_t soldier_frames_death6[] = {
|
||||
static mframe_t soldier_frames_death6[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1541,16 +1645,18 @@ mframe_t soldier_frames_death6[] = {
|
|||
{ai_move, 0, NULL}
|
||||
};
|
||||
|
||||
mmove_t soldier_move_death6 = {
|
||||
mmove_t soldier_move_death6 =
|
||||
{
|
||||
FRAME_death601,
|
||||
FRAME_death610,
|
||||
soldier_frames_death6,
|
||||
soldier_dead
|
||||
FRAME_death610,
|
||||
soldier_frames_death6,
|
||||
soldier_dead
|
||||
};
|
||||
|
||||
void
|
||||
soldier_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
|
||||
int damage, vec3_t point /* unused */)
|
||||
soldier_die(edict_t *self, edict_t *inflictor /* unused */,
|
||||
edict_t *attacker /* unused */, int damage,
|
||||
vec3_t point /* unused */)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -1566,11 +1672,14 @@ soldier_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
|
||||
for (n = 0; n < 3; n++)
|
||||
{
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
}
|
||||
|
||||
ThrowGib(self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
|
||||
ThrowGib(self, "models/objects/gibs/chest/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
ThrowHead(self, "models/objects/gibs/head2/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
self->deadflag = DEAD_DEAD;
|
||||
return;
|
||||
}
|
||||
|
@ -1687,7 +1796,7 @@ soldier_duck(edict_t *self, float eta)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t soldier_frames_blind[] = {
|
||||
static mframe_t soldier_frames_blind[] = {
|
||||
{ai_move, 0, soldier_idle},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1748,6 +1857,13 @@ SP_monster_soldier_x(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
// Force recaching at next footstep to ensure
|
||||
// that the sound indices are correct.
|
||||
sound_step = 0;
|
||||
sound_step2 = 0;
|
||||
sound_step3 = 0;
|
||||
sound_step4 = 0;
|
||||
|
||||
self->s.modelindex = gi.modelindex("models/monsters/soldier/tris.md2");
|
||||
self->monsterinfo.scale = MODEL_SCALE;
|
||||
VectorSet(self->mins, -16, -16, -24);
|
||||
|
@ -1809,6 +1925,9 @@ SP_monster_soldier_light(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
self->health = 20;
|
||||
self->gib_health = -30;
|
||||
|
||||
SP_monster_soldier_x(self);
|
||||
|
||||
sound_pain_light = gi.soundindex("soldier/solpain2.wav");
|
||||
|
@ -1818,9 +1937,6 @@ SP_monster_soldier_light(edict_t *self)
|
|||
gi.soundindex("soldier/solatck2.wav");
|
||||
|
||||
self->s.skinnum = 0;
|
||||
self->health = 20;
|
||||
self->gib_health = -30;
|
||||
|
||||
self->monsterinfo.blindfire = true;
|
||||
}
|
||||
|
||||
|
@ -1843,6 +1959,9 @@ SP_monster_soldier(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
self->health = 30;
|
||||
self->gib_health = -30;
|
||||
|
||||
SP_monster_soldier_x(self);
|
||||
|
||||
sound_pain = gi.soundindex("soldier/solpain1.wav");
|
||||
|
@ -1850,8 +1969,6 @@ SP_monster_soldier(edict_t *self)
|
|||
gi.soundindex("soldier/solatck1.wav");
|
||||
|
||||
self->s.skinnum = 2;
|
||||
self->health = 30;
|
||||
self->gib_health = -30;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1873,6 +1990,9 @@ SP_monster_soldier_ss(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
self->health = 40;
|
||||
self->gib_health = -30;
|
||||
|
||||
SP_monster_soldier_x(self);
|
||||
|
||||
sound_pain_ss = gi.soundindex("soldier/solpain3.wav");
|
||||
|
@ -1880,6 +2000,4 @@ SP_monster_soldier_ss(edict_t *self)
|
|||
gi.soundindex("soldier/solatck3.wav");
|
||||
|
||||
self->s.skinnum = 4;
|
||||
self->health = 40;
|
||||
self->gib_health = -30;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ stalker_idle_noise(edict_t *self)
|
|||
gi.sound(self, CHAN_WEAPON, sound_idle, 0.5, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_idle[] = {
|
||||
static mframe_t stalker_frames_idle[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -231,7 +231,7 @@ mmove_t stalker_move_idle = {
|
|||
stalker_stand
|
||||
};
|
||||
|
||||
mframe_t stalker_frames_idle2[] = {
|
||||
static mframe_t stalker_frames_idle2[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -274,7 +274,7 @@ stalker_idle(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_stand[] = {
|
||||
static mframe_t stalker_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -327,7 +327,7 @@ stalker_stand(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_run[] = {
|
||||
static mframe_t stalker_frames_run[] = {
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 17, NULL},
|
||||
{ai_run, 21, NULL},
|
||||
|
@ -359,7 +359,7 @@ stalker_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_walk[] = {
|
||||
static mframe_t stalker_frames_walk[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 8, NULL},
|
||||
|
@ -389,7 +389,7 @@ stalker_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &stalker_move_walk;
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_reactivate[] = {
|
||||
static mframe_t stalker_frames_reactivate[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -448,7 +448,7 @@ stalker_heal(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_false_death[] = {
|
||||
static mframe_t stalker_frames_false_death[] = {
|
||||
{ai_move, 0, stalker_heal},
|
||||
{ai_move, 0, stalker_heal},
|
||||
{ai_move, 0, stalker_heal},
|
||||
|
@ -480,7 +480,7 @@ stalker_false_death(edict_t *self)
|
|||
self->monsterinfo.currentmove = &stalker_move_false_death;
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_false_death_start[] = {
|
||||
static mframe_t stalker_frames_false_death_start[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -515,7 +515,7 @@ stalker_false_death_start(edict_t *self)
|
|||
self->monsterinfo.currentmove = &stalker_move_false_death_start;
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_pain[] = {
|
||||
static mframe_t stalker_frames_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -678,7 +678,7 @@ stalker_shoot_attack2(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_shoot[] = {
|
||||
static mframe_t stalker_frames_shoot[] = {
|
||||
{ai_charge, 13, NULL},
|
||||
{ai_charge, 17, stalker_shoot_attack},
|
||||
{ai_charge, 21, NULL},
|
||||
|
@ -748,7 +748,7 @@ stalker_swing_attack(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_swing_l[] = {
|
||||
static mframe_t stalker_frames_swing_l[] = {
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 6, NULL},
|
||||
|
@ -766,7 +766,7 @@ mmove_t stalker_move_swing_l = {
|
|||
stalker_run
|
||||
};
|
||||
|
||||
mframe_t stalker_frames_swing_r[] = {
|
||||
static mframe_t stalker_frames_swing_r[] = {
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 6, NULL},
|
||||
{ai_charge, 6, stalker_swing_attack},
|
||||
|
@ -1085,7 +1085,7 @@ stalker_jump_straightup(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_jump_straightup[] = {
|
||||
static mframe_t stalker_frames_jump_straightup[] = {
|
||||
{ai_move, 1, stalker_jump_straightup},
|
||||
{ai_move, 1, stalker_jump_wait_land},
|
||||
{ai_move, -1, NULL},
|
||||
|
@ -1110,7 +1110,7 @@ stalker_dodge_jump(edict_t *self)
|
|||
self->monsterinfo.currentmove = &stalker_move_jump_straightup;
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_dodge_run[] = {
|
||||
static mframe_t stalker_frames_dodge_run[] = {
|
||||
{ai_run, 13, NULL},
|
||||
{ai_run, 17, NULL},
|
||||
{ai_run, 21, NULL},
|
||||
|
@ -1220,7 +1220,7 @@ stalker_jump_wait_land(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_jump_up[] = {
|
||||
static mframe_t stalker_frames_jump_up[] = {
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -8, NULL},
|
||||
{ai_move, -8, NULL},
|
||||
|
@ -1238,7 +1238,7 @@ mmove_t stalker_move_jump_up = {
|
|||
stalker_run
|
||||
};
|
||||
|
||||
mframe_t stalker_frames_jump_down[] = {
|
||||
static mframe_t stalker_frames_jump_down[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1357,7 +1357,7 @@ stalker_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t stalker_frames_death[] = {
|
||||
static mframe_t stalker_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, -5, NULL},
|
||||
{ai_move, -10, NULL},
|
||||
|
|
|
@ -54,7 +54,7 @@ supertank_search(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t supertank_frames_stand[] = {
|
||||
static mframe_t supertank_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -135,7 +135,7 @@ supertank_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &supertank_move_stand;
|
||||
}
|
||||
|
||||
mframe_t supertank_frames_run[] = {
|
||||
static mframe_t supertank_frames_run[] = {
|
||||
{ai_run, 12, TreadSound},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 12, NULL},
|
||||
|
@ -163,7 +163,7 @@ mmove_t supertank_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_forward[] = {
|
||||
static mframe_t supertank_frames_forward[] = {
|
||||
{ai_walk, 4, TreadSound},
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 4, NULL},
|
||||
|
@ -231,7 +231,7 @@ supertank_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t supertank_frames_turn_right[] = {
|
||||
static mframe_t supertank_frames_turn_right[] = {
|
||||
{ai_move, 0, TreadSound},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -259,7 +259,7 @@ mmove_t supertank_move_turn_right = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_turn_left[] = {
|
||||
static mframe_t supertank_frames_turn_left[] = {
|
||||
{ai_move, 0, TreadSound},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -287,7 +287,7 @@ mmove_t supertank_move_turn_left = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_pain3[] = {
|
||||
static mframe_t supertank_frames_pain3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -301,7 +301,7 @@ mmove_t supertank_move_pain3 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_pain2[] = {
|
||||
static mframe_t supertank_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -315,7 +315,7 @@ mmove_t supertank_move_pain2 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_pain1[] = {
|
||||
static mframe_t supertank_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -329,7 +329,7 @@ mmove_t supertank_move_pain1 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_death1[] = {
|
||||
static mframe_t supertank_frames_death1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -363,7 +363,7 @@ mmove_t supertank_move_death = {
|
|||
supertank_dead
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_backward[] = {
|
||||
static mframe_t supertank_frames_backward[] = {
|
||||
{ai_walk, 0, TreadSound},
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 0, NULL},
|
||||
|
@ -391,7 +391,7 @@ mmove_t supertank_move_backward = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_attack4[] = {
|
||||
static mframe_t supertank_frames_attack4[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -407,7 +407,7 @@ mmove_t supertank_move_attack4 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_attack3[] = {
|
||||
static mframe_t supertank_frames_attack3[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -444,7 +444,7 @@ mmove_t supertank_move_attack3 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_attack2[] = {
|
||||
static mframe_t supertank_frames_attack2[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -481,7 +481,7 @@ mmove_t supertank_move_attack2 = {
|
|||
supertank_run
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_attack1[] = {
|
||||
static mframe_t supertank_frames_attack1[] = {
|
||||
{ai_charge, 0, supertankMachineGun},
|
||||
{ai_charge, 0, supertankMachineGun},
|
||||
{ai_charge, 0, supertankMachineGun},
|
||||
|
@ -497,7 +497,7 @@ mmove_t supertank_move_attack1 = {
|
|||
supertank_reattack1
|
||||
};
|
||||
|
||||
mframe_t supertank_frames_end_attack1[] = {
|
||||
static mframe_t supertank_frames_end_attack1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -78,7 +78,7 @@ tank_idle(edict_t *self)
|
|||
gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
mframe_t tank_frames_stand[] = {
|
||||
static mframe_t tank_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -129,7 +129,7 @@ tank_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &tank_move_stand;
|
||||
}
|
||||
|
||||
mframe_t tank_frames_start_walk[] = {
|
||||
static mframe_t tank_frames_start_walk[] = {
|
||||
{ai_walk, 0, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
{ai_walk, 6, NULL},
|
||||
|
@ -143,7 +143,7 @@ mmove_t tank_move_start_walk = {
|
|||
tank_walk
|
||||
};
|
||||
|
||||
mframe_t tank_frames_walk[] = {
|
||||
static mframe_t tank_frames_walk[] = {
|
||||
{ai_walk, 4, NULL},
|
||||
{ai_walk, 5, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
|
@ -169,7 +169,7 @@ mmove_t tank_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t tank_frames_stop_walk[] = {
|
||||
static mframe_t tank_frames_stop_walk[] = {
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 3, NULL},
|
||||
{ai_walk, 2, NULL},
|
||||
|
@ -195,7 +195,7 @@ tank_walk(edict_t *self)
|
|||
self->monsterinfo.currentmove = &tank_move_walk;
|
||||
}
|
||||
|
||||
mframe_t tank_frames_start_run[] = {
|
||||
static mframe_t tank_frames_start_run[] = {
|
||||
{ai_run, 0, NULL},
|
||||
{ai_run, 6, NULL},
|
||||
{ai_run, 6, NULL},
|
||||
|
@ -209,7 +209,7 @@ mmove_t tank_move_start_run = {
|
|||
tank_run
|
||||
};
|
||||
|
||||
mframe_t tank_frames_run[] = {
|
||||
static mframe_t tank_frames_run[] = {
|
||||
{ai_run, 4, NULL},
|
||||
{ai_run, 5, NULL},
|
||||
{ai_run, 3, NULL},
|
||||
|
@ -235,7 +235,7 @@ mmove_t tank_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t tank_frames_stop_run[] = {
|
||||
static mframe_t tank_frames_stop_run[] = {
|
||||
{ai_run, 3, NULL},
|
||||
{ai_run, 3, NULL},
|
||||
{ai_run, 2, NULL},
|
||||
|
@ -284,7 +284,7 @@ tank_run(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t tank_frames_pain1[] = {
|
||||
static mframe_t tank_frames_pain1[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -298,7 +298,7 @@ mmove_t tank_move_pain1 = {
|
|||
tank_run
|
||||
};
|
||||
|
||||
mframe_t tank_frames_pain2[] = {
|
||||
static mframe_t tank_frames_pain2[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -313,7 +313,7 @@ mmove_t tank_move_pain2 = {
|
|||
tank_run
|
||||
};
|
||||
|
||||
mframe_t tank_frames_pain3[] = {
|
||||
static mframe_t tank_frames_pain3[] = {
|
||||
{ai_move, -7, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -547,64 +547,26 @@ TankRocket(edict_t *self)
|
|||
|
||||
VectorNormalize(dir);
|
||||
|
||||
// Blindfire doesn't check target (done in checkattack). Paranoia:
|
||||
// Make sure we're not shooting a target right next to us.
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (blindfire)
|
||||
{
|
||||
// Blindfire has different fail criteria for the trace
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
/* blindfire has different fail criteria for the trace */
|
||||
if (!blind_rocket_ok(self, start, right, target, 20.0f, dir))
|
||||
{
|
||||
monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try shifting the target to the left a little (to help counter large offset)
|
||||
VectorCopy(target, vec);
|
||||
VectorMA(vec, -20, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
{
|
||||
monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OK, that failed. Try to the right.
|
||||
VectorCopy(target, vec);
|
||||
VectorMA(vec, 20, right, vec);
|
||||
VectorSubtract(vec, start, dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
|
||||
{
|
||||
monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number);
|
||||
}
|
||||
else if ((g_showlogic) && (g_showlogic->value))
|
||||
{
|
||||
gi.dprintf ("tank avoiding blindfire shot\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
|
||||
|
||||
if (trace.ent == self->enemy || trace.ent == world)
|
||||
if (((trace.ent != self->enemy) && (trace.ent != world)) ||
|
||||
((trace.fraction <= 0.5f) && !trace.ent->client))
|
||||
{
|
||||
if (trace.fraction > 0.5 || (trace.ent && trace.ent->client))
|
||||
{
|
||||
monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -657,7 +619,7 @@ TankMachineGun(edict_t *self)
|
|||
DEFAULT_BULLET_VSPREAD, flash_number);
|
||||
}
|
||||
|
||||
mframe_t tank_frames_attack_blast[] = {
|
||||
static mframe_t tank_frames_attack_blast[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -682,7 +644,7 @@ mmove_t tank_move_attack_blast = {
|
|||
tank_reattack_blaster
|
||||
};
|
||||
|
||||
mframe_t tank_frames_reattack_blast[] = {
|
||||
static mframe_t tank_frames_reattack_blast[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, TankBlaster},
|
||||
|
@ -698,7 +660,7 @@ mmove_t tank_move_reattack_blast = {
|
|||
tank_reattack_blaster
|
||||
};
|
||||
|
||||
mframe_t tank_frames_attack_post_blast[] = {
|
||||
static mframe_t tank_frames_attack_post_blast[] = {
|
||||
{ai_move, 0, NULL}, /* 17 */
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
|
@ -752,7 +714,7 @@ tank_poststrike(edict_t *self)
|
|||
tank_run(self);
|
||||
}
|
||||
|
||||
mframe_t tank_frames_attack_strike[] = {
|
||||
static mframe_t tank_frames_attack_strike[] = {
|
||||
{ai_move, 3, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
{ai_move, 2, NULL},
|
||||
|
@ -800,7 +762,7 @@ mmove_t tank_move_attack_strike = {
|
|||
tank_poststrike
|
||||
};
|
||||
|
||||
mframe_t tank_frames_attack_pre_rocket[] = {
|
||||
static mframe_t tank_frames_attack_pre_rocket[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -833,7 +795,7 @@ mmove_t tank_move_attack_pre_rocket = {
|
|||
tank_doattack_rocket
|
||||
};
|
||||
|
||||
mframe_t tank_frames_attack_fire_rocket[] = {
|
||||
static mframe_t tank_frames_attack_fire_rocket[] = {
|
||||
{ai_charge, -3, NULL}, /* Loop Start 22 */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, TankRocket}, /* 24 */
|
||||
|
@ -852,7 +814,7 @@ mmove_t tank_move_attack_fire_rocket = {
|
|||
tank_refire_rocket
|
||||
};
|
||||
|
||||
mframe_t tank_frames_attack_post_rocket[] = {
|
||||
static mframe_t tank_frames_attack_post_rocket[] = {
|
||||
{ai_charge, 0, NULL}, /* 31 */
|
||||
{ai_charge, -1, NULL},
|
||||
{ai_charge, -1, NULL},
|
||||
|
@ -887,7 +849,7 @@ mmove_t tank_move_attack_post_rocket = {
|
|||
tank_run
|
||||
};
|
||||
|
||||
mframe_t tank_frames_attack_chain[] = {
|
||||
static mframe_t tank_frames_attack_chain[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -1091,7 +1053,7 @@ tank_dead(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
mframe_t tank_frames_death1[] = {
|
||||
static mframe_t tank_frames_death1[] = {
|
||||
{ai_move, -7, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
{ai_move, -2, NULL},
|
||||
|
|
|
@ -346,7 +346,7 @@ turret_search(edict_t *self)
|
|||
{
|
||||
}
|
||||
|
||||
mframe_t turret_frames_stand[] = {
|
||||
static mframe_t turret_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
@ -369,7 +369,7 @@ turret_stand(edict_t *self)
|
|||
self->monsterinfo.currentmove = &turret_move_stand;
|
||||
}
|
||||
|
||||
mframe_t turret_frames_ready_gun[] = {
|
||||
static mframe_t turret_frames_ready_gun[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -399,7 +399,7 @@ turret_ready_gun(edict_t *self)
|
|||
self->monsterinfo.currentmove = &turret_move_ready_gun;
|
||||
}
|
||||
|
||||
mframe_t turret_frames_seek[] = {
|
||||
static mframe_t turret_frames_seek[] = {
|
||||
{ai_walk, 0, TurretAim},
|
||||
{ai_walk, 0, TurretAim}
|
||||
};
|
||||
|
@ -429,7 +429,7 @@ turret_walk(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t turret_frames_run[] = {
|
||||
static mframe_t turret_frames_run[] = {
|
||||
{ai_run, 0, TurretAim},
|
||||
{ai_run, 0, TurretAim}
|
||||
};
|
||||
|
@ -653,7 +653,7 @@ TurretFireBlind(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t turret_frames_fire[] = {
|
||||
static mframe_t turret_frames_fire[] = {
|
||||
{ai_run, 0, TurretFire},
|
||||
{ai_run, 0, TurretAim},
|
||||
{ai_run, 0, TurretAim},
|
||||
|
@ -668,7 +668,7 @@ mmove_t turret_move_fire = {
|
|||
};
|
||||
|
||||
/* the blind frames need to aim first */
|
||||
mframe_t turret_frames_fire_blind[] = {
|
||||
static mframe_t turret_frames_fire_blind[] = {
|
||||
{ai_run, 0, TurretAim},
|
||||
{ai_run, 0, TurretAim},
|
||||
{ai_run, 0, TurretAim},
|
||||
|
@ -887,6 +887,7 @@ turret_wake(edict_t *self)
|
|||
self->monsterinfo.sight = turret_sight;
|
||||
self->monsterinfo.search = turret_search;
|
||||
self->monsterinfo.currentmove = &turret_move_stand;
|
||||
|
||||
self->takedamage = DAMAGE_AIM;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->monsterinfo.aiflags |= AI_DO_NOT_COUNT;
|
||||
|
@ -895,6 +896,11 @@ turret_wake(edict_t *self)
|
|||
|
||||
stationarymonster_start(self);
|
||||
|
||||
if (self->think)
|
||||
{
|
||||
self->think(self);
|
||||
}
|
||||
|
||||
if (self->spawnflags & SPAWN_MACHINEGUN)
|
||||
{
|
||||
self->s.skinnum = 1;
|
||||
|
@ -915,6 +921,11 @@ turret_activate(edict_t *self, edict_t *other, edict_t *activator)
|
|||
vec3_t forward;
|
||||
edict_t *base;
|
||||
|
||||
if (self->movetype == MOVETYPE_PUSH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
|
||||
if (!self->speed)
|
||||
|
@ -950,6 +961,10 @@ turret_activate(edict_t *self, edict_t *other, edict_t *activator)
|
|||
{
|
||||
VectorSet(forward, 0, -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorClear(forward);
|
||||
}
|
||||
|
||||
/* start up the turret */
|
||||
VectorMA(self->s.origin, 32, forward, endpos);
|
||||
|
@ -980,7 +995,6 @@ turret_checkattack(edict_t *self)
|
|||
vec3_t spot1, spot2;
|
||||
float chance, nexttime;
|
||||
trace_t tr;
|
||||
int enemy_range;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
|
@ -1048,20 +1062,6 @@ turret_checkattack(edict_t *self)
|
|||
return false;
|
||||
}
|
||||
|
||||
enemy_range = range(self, self->enemy);
|
||||
|
||||
if (enemy_range == RANGE_MELEE)
|
||||
{
|
||||
/* don't always melee in easy mode */
|
||||
if ((skill->value == SKILL_EASY) && (rand() & 3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self->monsterinfo.attack_state = AS_MISSILE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self->spawnflags & SPAWN_ROCKET)
|
||||
{
|
||||
chance = 0.10;
|
||||
|
|
|
@ -452,7 +452,7 @@ widow_step(edict_t *self)
|
|||
gi.sound(self, CHAN_BODY, gi.soundindex("widow/bwstep3.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
mframe_t widow_frames_stand[] = {
|
||||
static mframe_t widow_frames_stand[] = {
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
{ai_stand, 0, NULL},
|
||||
|
@ -473,7 +473,7 @@ mmove_t widow_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_walk[] = {
|
||||
static mframe_t widow_frames_walk[] = {
|
||||
/* auto generated numbers */
|
||||
{ai_walk, 2.79, widow_step},
|
||||
{ai_walk, 2.77, NULL},
|
||||
|
@ -497,7 +497,7 @@ mmove_t widow_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_run[] = {
|
||||
static mframe_t widow_frames_run[] = {
|
||||
{ai_run, 2.79, widow_step},
|
||||
{ai_run, 2.77, NULL},
|
||||
{ai_run, 3.53, NULL},
|
||||
|
@ -532,7 +532,7 @@ widow_stepshoot(edict_t *self)
|
|||
WidowBlaster(self);
|
||||
}
|
||||
|
||||
mframe_t widow_frames_run_attack[] = {
|
||||
static mframe_t widow_frames_run_attack[] = {
|
||||
{ai_charge, 13, widow_stepshoot},
|
||||
{ai_charge, 11.72, WidowBlaster},
|
||||
{ai_charge, 18.04, WidowBlaster},
|
||||
|
@ -588,7 +588,7 @@ widow_start_run_12(edict_t *self)
|
|||
self->monsterinfo.nextframe = FRAME_walk12;
|
||||
}
|
||||
|
||||
mframe_t widow_frames_attack_pre_blaster[] = {
|
||||
static mframe_t widow_frames_attack_pre_blaster[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, widow_attack_blaster}
|
||||
|
@ -601,7 +601,7 @@ mmove_t widow_move_attack_pre_blaster = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_blaster[] = {
|
||||
static mframe_t widow_frames_attack_blaster[] = {
|
||||
{ai_charge, 0, widow_reattack_blaster}, /* straight ahead */
|
||||
{ai_charge, 0, widow_reattack_blaster}, /* 100 degrees right */
|
||||
{ai_charge, 0, widow_reattack_blaster},
|
||||
|
@ -630,7 +630,7 @@ mmove_t widow_move_attack_blaster = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_post_blaster[] = {
|
||||
static mframe_t widow_frames_attack_post_blaster[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
@ -642,7 +642,7 @@ mmove_t widow_move_attack_post_blaster = {
|
|||
widow_run
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_post_blaster_r[] = {
|
||||
static mframe_t widow_frames_attack_post_blaster_r[] = {
|
||||
{ai_charge, -2, NULL},
|
||||
{ai_charge, -10, NULL},
|
||||
{ai_charge, -2, NULL},
|
||||
|
@ -657,7 +657,7 @@ mmove_t widow_move_attack_post_blaster_r = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_post_blaster_l[] = {
|
||||
static mframe_t widow_frames_attack_post_blaster_l[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 14, NULL},
|
||||
{ai_charge, -2, NULL},
|
||||
|
@ -746,7 +746,7 @@ widow_rail_done(edict_t *self)
|
|||
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
|
||||
}
|
||||
|
||||
mframe_t widow_frames_attack_pre_rail[] = {
|
||||
static mframe_t widow_frames_attack_pre_rail[] = {
|
||||
{ai_charge, 0, widow_start_rail},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -760,7 +760,7 @@ mmove_t widow_move_attack_pre_rail = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_rail[] = {
|
||||
static mframe_t widow_frames_attack_rail[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, WidowSaveLoc},
|
||||
|
@ -779,7 +779,7 @@ mmove_t widow_move_attack_rail = {
|
|||
widow_run
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_rail_r[] = {
|
||||
static mframe_t widow_frames_attack_rail_r[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, WidowSaveLoc},
|
||||
|
@ -797,7 +797,7 @@ mmove_t widow_move_attack_rail_r = {
|
|||
widow_run
|
||||
};
|
||||
|
||||
mframe_t widow_frames_attack_rail_l[] = {
|
||||
static mframe_t widow_frames_attack_rail_l[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, WidowSaveLoc},
|
||||
|
@ -864,7 +864,7 @@ widow_done_spawn(edict_t *self)
|
|||
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
|
||||
}
|
||||
|
||||
mframe_t widow_frames_spawn[] = {
|
||||
static mframe_t widow_frames_spawn[] = {
|
||||
{ai_charge, 0, NULL}, /* 1 */
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
|
@ -892,7 +892,7 @@ mmove_t widow_move_spawn = {
|
|||
widow_run
|
||||
};
|
||||
|
||||
mframe_t widow_frames_pain_heavy[] = {
|
||||
static mframe_t widow_frames_pain_heavy[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -915,7 +915,7 @@ mmove_t widow_move_pain_heavy = {
|
|||
widow_run
|
||||
};
|
||||
|
||||
mframe_t widow_frames_pain_light[] = {
|
||||
static mframe_t widow_frames_pain_light[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL}
|
||||
|
@ -994,7 +994,7 @@ spawn_out_do(edict_t *self)
|
|||
G_FreeEdict(self);
|
||||
}
|
||||
|
||||
mframe_t widow_frames_death[] = {
|
||||
static mframe_t widow_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -1057,7 +1057,7 @@ widow_attack_kick(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t widow_frames_attack_kick[] = {
|
||||
static mframe_t widow_frames_attack_kick[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -292,7 +292,7 @@ widow2_ready_spawn(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t widow2_frames_stand[] = {
|
||||
static mframe_t widow2_frames_stand[] = {
|
||||
{ai_stand, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -303,7 +303,7 @@ mmove_t widow2_move_stand = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_walk[] = {
|
||||
static mframe_t widow2_frames_walk[] = {
|
||||
{ai_walk, 9.01, NULL},
|
||||
{ai_walk, 7.55, NULL},
|
||||
{ai_walk, 7.01, NULL},
|
||||
|
@ -322,7 +322,7 @@ mmove_t widow2_move_walk = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_run[] = {
|
||||
static mframe_t widow2_frames_run[] = {
|
||||
{ai_run, 9.01, NULL},
|
||||
{ai_run, 7.55, NULL},
|
||||
{ai_run, 7.01, NULL},
|
||||
|
@ -341,7 +341,7 @@ mmove_t widow2_move_run = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_attack_pre_beam[] = {
|
||||
static mframe_t widow2_frames_attack_pre_beam[] = {
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
|
@ -356,7 +356,7 @@ mmove_t widow2_move_attack_pre_beam = {
|
|||
};
|
||||
|
||||
/* Loop this */
|
||||
mframe_t widow2_frames_attack_beam[] = {
|
||||
static mframe_t widow2_frames_attack_beam[] = {
|
||||
{ai_charge, 0, Widow2Beam},
|
||||
{ai_charge, 0, Widow2Beam},
|
||||
{ai_charge, 0, Widow2Beam},
|
||||
|
@ -371,7 +371,7 @@ mmove_t widow2_move_attack_beam = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_attack_post_beam[] = {
|
||||
static mframe_t widow2_frames_attack_post_beam[] = {
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 4, NULL}
|
||||
|
@ -455,7 +455,7 @@ widow2_disrupt_reattack(edict_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
mframe_t widow2_frames_attack_disrupt[] = {
|
||||
static mframe_t widow2_frames_attack_disrupt[] = {
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, NULL},
|
||||
{ai_charge, 2, Widow2SaveDisruptLoc},
|
||||
|
@ -515,7 +515,7 @@ Widow2StartSweep(edict_t *self)
|
|||
Widow2SaveBeamTarget(self);
|
||||
}
|
||||
|
||||
mframe_t widow2_frames_spawn[] = {
|
||||
static mframe_t widow2_frames_spawn[] = {
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, widow_start_spawn},
|
||||
|
@ -725,7 +725,7 @@ Widow2Toss(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
mframe_t widow2_frames_tongs[] = {
|
||||
static mframe_t widow2_frames_tongs[] = {
|
||||
{ai_charge, 0, Widow2Tongue},
|
||||
{ai_charge, 0, Widow2Tongue},
|
||||
{ai_charge, 0, Widow2Tongue},
|
||||
|
@ -743,7 +743,7 @@ mmove_t widow2_move_tongs = {
|
|||
widow2_run
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_pain[] = {
|
||||
static mframe_t widow2_frames_pain[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -758,7 +758,7 @@ mmove_t widow2_move_pain = {
|
|||
widow2_run
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_death[] = {
|
||||
static mframe_t widow2_frames_death[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, WidowExplosion1}, /* 3 boom */
|
||||
|
@ -820,7 +820,7 @@ mmove_t widow2_move_death = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_dead[] = {
|
||||
static mframe_t widow2_frames_dead[] = {
|
||||
{ai_move, 0, widow2_start_searching},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -847,7 +847,7 @@ mmove_t widow2_move_dead = {
|
|||
NULL
|
||||
};
|
||||
|
||||
mframe_t widow2_frames_really_dead[] = {
|
||||
static mframe_t widow2_frames_really_dead[] = {
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
{ai_move, 0, NULL},
|
||||
|
|
|
@ -103,7 +103,7 @@ SP_info_player_coop_lava(edict_t *self)
|
|||
* as well as yaw. 'pitch yaw roll'
|
||||
*/
|
||||
void
|
||||
SP_info_player_intermission(void)
|
||||
SP_info_player_intermission(edict_t *ent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -730,8 +730,8 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
/* don't toss gibs if we got vaped by the nuke */
|
||||
if (!(self->flags & FL_NOGIB))
|
||||
{
|
||||
/* gib */
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
/* gib (play sound at end of server frame) */
|
||||
self->sounds = gi.soundindex( "misc/udeath.wav");
|
||||
|
||||
/* more meaty gibs for your dollar! */
|
||||
if ((deathmatch->value) && (self->health < -80))
|
||||
|
@ -788,7 +788,11 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
}
|
||||
}
|
||||
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand() % 4) + 1)), 1, ATTN_NORM, 0);
|
||||
/* play sound at end of server frame */
|
||||
if (!self->sounds)
|
||||
{
|
||||
self->sounds = gi.soundindex(va("*death%i.wav", (rand() % 4) + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -874,7 +878,7 @@ SaveClientData(void)
|
|||
|
||||
game.clients[i].pers.health = ent->health;
|
||||
game.clients[i].pers.max_health = ent->max_health;
|
||||
game.clients[i].pers.savedFlags = (ent->flags & (FL_GODMODE | FL_NOTARGET | FL_POWER_ARMOR));
|
||||
game.clients[i].pers.savedFlags = (ent->flags & (FL_GODMODE | FL_NOTARGET | FL_POWER_ARMOR | FL_DISGUISED));
|
||||
|
||||
if (coop->value)
|
||||
{
|
||||
|
|
|
@ -113,13 +113,15 @@ BeginIntermission(edict_t *targ)
|
|||
}
|
||||
|
||||
/* strip players of all keys between units */
|
||||
for (n = 0; n < MAX_ITEMS; n++)
|
||||
for (n = 0; n < game.num_items; n++)
|
||||
{
|
||||
if (itemlist[n].flags & IT_KEY)
|
||||
{
|
||||
client->client->pers.inventory[n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
client->client->pers.power_cubes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +398,7 @@ G_SetStats(edict_t *ent)
|
|||
|
||||
/* health */
|
||||
ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
|
||||
ent->client->ps.stats[STAT_HEALTH] = ent->health;
|
||||
ent->client->ps.stats[STAT_HEALTH] = (ent->health < -99) ? -99 : ent->health;
|
||||
|
||||
/* ammo */
|
||||
if (!ent->client->ammo_index)
|
||||
|
|
|
@ -63,6 +63,13 @@ P_DamageFeedback(edict_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
/* death/gib sound is now aggregated and played here */
|
||||
if (player->sounds)
|
||||
{
|
||||
gi.sound (player, CHAN_VOICE, player->sounds, 1, ATTN_NORM, 0);
|
||||
player->sounds = 0;
|
||||
}
|
||||
|
||||
client = player->client;
|
||||
|
||||
/* flash the backgrounds behind the status numbers */
|
||||
|
@ -131,7 +138,8 @@ P_DamageFeedback(edict_t *player)
|
|||
/* play an apropriate pain sound */
|
||||
if ((level.time > player->pain_debounce_time) &&
|
||||
!(player->flags & FL_GODMODE) &&
|
||||
(client->invincible_framenum <= level.framenum))
|
||||
(client->invincible_framenum <= level.framenum) &&
|
||||
player->health > 0)
|
||||
{
|
||||
r = 1 + (rand() & 1);
|
||||
player->pain_debounce_time = level.time + 0.7;
|
||||
|
@ -940,7 +948,8 @@ P_WorldEffects(void)
|
|||
{
|
||||
if ((current_player->health > 0) &&
|
||||
(current_player->pain_debounce_time <= level.time) &&
|
||||
(current_client->invincible_framenum < level.framenum))
|
||||
(current_client->invincible_framenum < level.framenum) &&
|
||||
!(current_player->flags & FL_GODMODE))
|
||||
{
|
||||
if (rand() & 1)
|
||||
{
|
||||
|
@ -1089,7 +1098,32 @@ G_SetClientEvent(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ent->groundentity && (xyspeed > 225))
|
||||
if (ent->health <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_footsteps->value == 1)
|
||||
{
|
||||
if (ent->groundentity && (xyspeed > 225))
|
||||
{
|
||||
if ((int)(current_client->bobtime + bobmove) != bobcycle)
|
||||
{
|
||||
ent->s.event = EV_FOOTSTEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g_footsteps->value == 2)
|
||||
{
|
||||
if (ent->groundentity)
|
||||
{
|
||||
if ((int)(current_client->bobtime + bobmove) != bobcycle)
|
||||
{
|
||||
ent->s.event = EV_FOOTSTEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g_footsteps->value >= 3)
|
||||
{
|
||||
if ((int)(current_client->bobtime + bobmove) != bobcycle)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
#include "../header/local.h"
|
||||
#include "../monster/misc/player.h"
|
||||
#include <limits.h>
|
||||
|
||||
#define PLAYER_NOISE_SELF 0
|
||||
#define PLAYER_NOISE_IMPACT 1
|
||||
|
||||
#define FRAME_FIRE_FIRST (FRAME_ACTIVATE_LAST + 1)
|
||||
#define FRAME_IDLE_FIRST (FRAME_FIRE_LAST + 1)
|
||||
|
@ -63,10 +67,12 @@ P_DamageModifier(edict_t *ent)
|
|||
}
|
||||
|
||||
void
|
||||
P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward,
|
||||
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;
|
||||
|
||||
if (!client)
|
||||
{
|
||||
|
@ -85,13 +91,29 @@ P_ProjectSource(gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
P_ProjectSource2(gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward,
|
||||
P_ProjectSource2(edict_t *ent, vec3_t point, vec3_t distance, vec3_t forward,
|
||||
vec3_t right, vec3_t up, vec3_t result)
|
||||
{
|
||||
vec3_t _distance;
|
||||
gclient_t *client = ent->client;
|
||||
vec3_t _distance;
|
||||
|
||||
if (!client)
|
||||
{
|
||||
|
@ -110,6 +132,21 @@ P_ProjectSource2(gclient_t *client, vec3_t point, vec3_t distance, vec3_t forwar
|
|||
}
|
||||
|
||||
G_ProjectSource2(point, _distance, forward, right, up, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,12 +157,111 @@ P_ProjectSource2(gclient_t *client, vec3_t point, vec3_t distance, vec3_t forwar
|
|||
* Monsters that don't directly see the player can move
|
||||
* to a noise in hopes of seeing the player from there.
|
||||
*/
|
||||
static edict_t *
|
||||
PlayerNoise_Spawn(edict_t *who, int type)
|
||||
{
|
||||
edict_t *noise;
|
||||
|
||||
if (!who)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
noise = G_SpawnOptional();
|
||||
if (!noise)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
noise->classname = "player_noise";
|
||||
noise->spawnflags = type;
|
||||
VectorSet (noise->mins, -8, -8, -8);
|
||||
VectorSet (noise->maxs, 8, 8, 8);
|
||||
noise->owner = who;
|
||||
noise->svflags = SVF_NOCLIENT;
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
static void
|
||||
PlayerNoise_Verify(edict_t *who)
|
||||
{
|
||||
edict_t *e;
|
||||
edict_t *n1;
|
||||
edict_t *n2;
|
||||
|
||||
if (!who)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
n1 = who->mynoise;
|
||||
n2 = who->mynoise2;
|
||||
|
||||
if (n1 && !n1->inuse)
|
||||
{
|
||||
n1 = NULL;
|
||||
}
|
||||
|
||||
if (n2 && !n2->inuse)
|
||||
{
|
||||
n2 = NULL;
|
||||
}
|
||||
|
||||
if (n1 && n2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (e = g_edicts + 1 + game.maxclients; e < &g_edicts[globals.num_edicts]; e++)
|
||||
{
|
||||
if (!e->inuse || strcmp(e->classname, "player_noise") != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e->owner && e->owner != who)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
e->owner = who;
|
||||
|
||||
if (!n2 && (e->spawnflags == PLAYER_NOISE_IMPACT || n1))
|
||||
{
|
||||
n2 = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
n1 = e;
|
||||
}
|
||||
|
||||
if (n1 && n2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!n1)
|
||||
{
|
||||
n1 = PlayerNoise_Spawn(who, PLAYER_NOISE_SELF);
|
||||
}
|
||||
|
||||
if (!n2)
|
||||
{
|
||||
n2 = PlayerNoise_Spawn(who, PLAYER_NOISE_IMPACT);
|
||||
}
|
||||
|
||||
who->mynoise = n1;
|
||||
who->mynoise2 = n2;
|
||||
}
|
||||
|
||||
void
|
||||
PlayerNoise(edict_t *who, vec3_t where, int type)
|
||||
{
|
||||
edict_t *noise;
|
||||
|
||||
if (!who)
|
||||
if (!who || !who->client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -162,24 +298,7 @@ PlayerNoise(edict_t *who, vec3_t where, int type)
|
|||
}
|
||||
}
|
||||
|
||||
if (!who->mynoise)
|
||||
{
|
||||
noise = G_Spawn();
|
||||
noise->classname = "player_noise";
|
||||
VectorSet(noise->mins, -8, -8, -8);
|
||||
VectorSet(noise->maxs, 8, 8, 8);
|
||||
noise->owner = who;
|
||||
noise->svflags = SVF_NOCLIENT;
|
||||
who->mynoise = noise;
|
||||
|
||||
noise = G_Spawn();
|
||||
noise->classname = "player_noise";
|
||||
VectorSet(noise->mins, -8, -8, -8);
|
||||
VectorSet(noise->maxs, 8, 8, 8);
|
||||
noise->owner = who;
|
||||
noise->svflags = SVF_NOCLIENT;
|
||||
who->mynoise2 = noise;
|
||||
}
|
||||
PlayerNoise_Verify(who);
|
||||
|
||||
if ((type == PNOISE_SELF) || (type == PNOISE_WEAPON))
|
||||
{
|
||||
|
@ -188,6 +307,11 @@ PlayerNoise(edict_t *who, vec3_t where, int type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!who->mynoise)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
noise = who->mynoise;
|
||||
level.sound_entity = noise;
|
||||
level.sound_entity_framenum = level.framenum;
|
||||
|
@ -199,6 +323,11 @@ PlayerNoise(edict_t *who, vec3_t where, int type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!who->mynoise2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
noise = who->mynoise2;
|
||||
level.sound2_entity = noise;
|
||||
level.sound2_entity_framenum = level.framenum;
|
||||
|
@ -226,7 +355,8 @@ Pickup_Weapon(edict_t *ent, edict_t *other)
|
|||
|
||||
if ((((int)(dmflags->value) & DF_WEAPONS_STAY) || coop->value) && other->client->pers.inventory[index])
|
||||
{
|
||||
if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)))
|
||||
if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) &&
|
||||
(!coop_pickup_weapons->value || (ent->flags & FL_COOP_TAKEN)))
|
||||
{
|
||||
return false; /* leave the weapon for others to pickup */
|
||||
}
|
||||
|
@ -268,6 +398,7 @@ Pickup_Weapon(edict_t *ent, edict_t *other)
|
|||
if (coop->value)
|
||||
{
|
||||
ent->flags |= FL_RESPAWN;
|
||||
ent->flags |= FL_COOP_TAKEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,6 +585,31 @@ Think_Weapon(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Client (player) animation for changing weapon
|
||||
*/
|
||||
static void
|
||||
Change_Weap_Animation(edict_t *ent)
|
||||
{
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4 + 1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_pain304 + 1;
|
||||
ent->client->anim_end = FRAME_pain301;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the weapon ready if there is ammo
|
||||
*/
|
||||
|
@ -536,6 +692,9 @@ Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int F
|
|||
int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
|
||||
{
|
||||
int n;
|
||||
const unsigned short int change_speed = (g_swap_speed->value > 1)?
|
||||
(g_swap_speed->value < USHRT_MAX)? (unsigned short int)g_swap_speed->value : 1
|
||||
: 1;
|
||||
|
||||
if (!ent || !fire)
|
||||
{
|
||||
|
@ -549,41 +708,36 @@ Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int F
|
|||
|
||||
if (ent->client->weaponstate == WEAPON_DROPPING)
|
||||
{
|
||||
if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST)
|
||||
if (ent->client->ps.gunframe >= FRAME_DEACTIVATE_LAST - change_speed + 1)
|
||||
{
|
||||
ChangeWeapon(ent);
|
||||
return;
|
||||
}
|
||||
else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
|
||||
else if ( (FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) >= (4 * change_speed) )
|
||||
{
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
unsigned short int remainder = FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe;
|
||||
// "if (remainder == 4)" at change_speed == 1
|
||||
if ( ( remainder <= (4 * change_speed) )
|
||||
&& ( remainder > (3 * change_speed) ) )
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4 + 1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_pain304 + 1;
|
||||
ent->client->anim_end = FRAME_pain301;
|
||||
Change_Weap_Animation(ent);
|
||||
}
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
ent->client->ps.gunframe += change_speed;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_ACTIVATING)
|
||||
{
|
||||
if (ent->client->ps.gunframe == FRAME_ACTIVATE_LAST)
|
||||
if (ent->client->ps.gunframe >= FRAME_ACTIVATE_LAST - change_speed + 1)
|
||||
{
|
||||
ent->client->weaponstate = WEAPON_READY;
|
||||
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
ent->client->ps.gunframe += change_speed;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -592,20 +746,9 @@ Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int F
|
|||
ent->client->weaponstate = WEAPON_DROPPING;
|
||||
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
|
||||
|
||||
if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
|
||||
if ( (FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < (4 * change_speed) )
|
||||
{
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4 + 1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_pain304 + 1;
|
||||
ent->client->anim_end = FRAME_pain301;
|
||||
}
|
||||
Change_Weap_Animation(ent);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -760,7 +903,7 @@ weapon_grenade_fire(edict_t *ent, qboolean held)
|
|||
VectorSet(offset, 2, 6, ent->viewheight - 14);
|
||||
}
|
||||
|
||||
P_ProjectSource2(ent->client, ent->s.origin, offset,
|
||||
P_ProjectSource2(ent, ent->s.origin, offset,
|
||||
forward, right, up, start);
|
||||
|
||||
timer = ent->client->grenade_time - level.time;
|
||||
|
@ -1037,7 +1180,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;
|
||||
|
@ -1135,7 +1278,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 */
|
||||
|
@ -1198,7 +1341,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;
|
||||
|
@ -1440,7 +1583,7 @@ Machinegun_Fire(edict_t *ent)
|
|||
ent->client->kick_angles[0] = ent->client->machinegun_shots * -1.5;
|
||||
|
||||
/* raise the gun as it is firing */
|
||||
if (!deathmatch->value)
|
||||
if (!(deathmatch->value || g_machinegun_norecoil->value))
|
||||
{
|
||||
ent->client->machinegun_shots++;
|
||||
|
||||
|
@ -1454,7 +1597,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);
|
||||
|
||||
|
@ -1627,7 +1770,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, MOD_CHAINGUN);
|
||||
|
@ -1696,7 +1839,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)
|
||||
{
|
||||
|
@ -1758,7 +1901,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)
|
||||
{
|
||||
|
@ -1770,10 +1913,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);
|
||||
|
||||
|
@ -1853,7 +2021,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 */
|
||||
|
@ -1953,7 +2121,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++;
|
||||
|
@ -2016,7 +2184,7 @@ weapon_chainfist_fire(edict_t *ent)
|
|||
|
||||
/* set start point */
|
||||
VectorSet(offset, 0, 8, ent->viewheight - 4);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
fire_player_melee(ent, start, forward, CHAINFIST_REACH, damage,
|
||||
100, 1, MOD_CHAINFIST);
|
||||
|
@ -2043,7 +2211,7 @@ chainfist_smoke(edict_t *ent)
|
|||
|
||||
AngleVectors(ent->client->v_angle, forward, right, up);
|
||||
VectorSet(offset, 8, 8, ent->viewheight - 4);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, tempVec);
|
||||
P_ProjectSource(ent, offset, forward, right, tempVec);
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_CHAINFIST_SMOKE);
|
||||
|
@ -2181,7 +2349,7 @@ weapon_tracker_fire(edict_t *self)
|
|||
VectorSet(maxs, 16, 16, 16);
|
||||
AngleVectors(self->client->v_angle, forward, right, NULL);
|
||||
VectorSet(offset, 24, 8, self->viewheight - 8);
|
||||
P_ProjectSource(self->client, self->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(self, offset, forward, right, start);
|
||||
|
||||
VectorMA(start, 8192, forward, end);
|
||||
enemy = NULL;
|
||||
|
@ -2305,7 +2473,7 @@ weapon_etf_rifle_fire(edict_t *ent)
|
|||
|
||||
VectorCopy(ent->s.origin, tempPt);
|
||||
tempPt[2] += ent->viewheight;
|
||||
P_ProjectSource2(ent->client, tempPt, offset, forward, right, up, start);
|
||||
P_ProjectSource2(ent, tempPt, offset, forward, right, up, start);
|
||||
fire_flechette(ent, start, forward, damage, 750, kick);
|
||||
|
||||
/* send muzzle flash */
|
||||
|
@ -2408,7 +2576,7 @@ Heatbeam_Fire(edict_t *ent)
|
|||
|
||||
/* This offset is the "view" offset for the beam start (used by trace) */
|
||||
VectorSet(offset, 7, 2, ent->viewheight - 3);
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
P_ProjectSource(ent, offset, forward, right, start);
|
||||
|
||||
/* This offset is the entity offset */
|
||||
VectorSet(offset, 2, 7, -3);
|
||||
|
|
|
@ -51,19 +51,23 @@
|
|||
* load older savegames. This should be bumped if the files
|
||||
* in tables/ are changed, otherwise strange things may happen.
|
||||
*/
|
||||
#define SAVEGAMEVER "YQ2-4"
|
||||
#define SAVEGAMEVER "YQ2-6"
|
||||
|
||||
#ifndef BUILD_DATE
|
||||
#define BUILD_DATE __DATE__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This macros are used to prohibit loading of savegames
|
||||
* created on other systems or architectures. This will
|
||||
* crash q2 in spectacular ways
|
||||
*/
|
||||
#ifndef OSTYPE
|
||||
#error OSTYPE should be defined by the build system
|
||||
#ifndef YQ2OSTYPE
|
||||
#error YQ2OSTYPE should be defined by the build system
|
||||
#endif
|
||||
|
||||
#ifndef ARCH
|
||||
#error ARCH should be defined by the build system
|
||||
#ifndef YQ2ARCH
|
||||
#error YQ2ARCH should be defined by the build system
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -71,29 +75,29 @@
|
|||
* macros, implemented by savegame version YQ2-2.
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
#define OSTYPE_1 "MacOS X"
|
||||
#define YQ2OSTYPE_1 "MacOS X"
|
||||
#elif defined(__FreeBSD__)
|
||||
#define OSTYPE_1 "FreeBSD"
|
||||
#define YQ2OSTYPE_1 "FreeBSD"
|
||||
#elif defined(__OpenBSD__)
|
||||
#define OSTYPE_1 "OpenBSD"
|
||||
#define YQ2OSTYPE_1 "OpenBSD"
|
||||
#elif defined(__linux__)
|
||||
#define OSTYPE_1 "Linux"
|
||||
#define YQ2OSTYPE_1 "Linux"
|
||||
#elif defined(_WIN32)
|
||||
#define OSTYPE_1 "Windows"
|
||||
#define YQ2OSTYPE_1 "Windows"
|
||||
#else
|
||||
#define OSTYPE_1 "Unknown"
|
||||
#define YQ2OSTYPE_1 "Unknown"
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
#define ARCH_1 "i386"
|
||||
#define YQ2ARCH_1 "i386"
|
||||
#elif defined(__x86_64__)
|
||||
#define ARCH_1 "amd64"
|
||||
#define YQ2ARCH_1 "amd64"
|
||||
#elif defined(__sparc__)
|
||||
#define ARCH_1 "sparc64"
|
||||
#define YQ2ARCH_1 "sparc64"
|
||||
#elif defined(__ia64__)
|
||||
#define ARCH_1 "ia64"
|
||||
#define YQ2ARCH_1 "ia64"
|
||||
#else
|
||||
#define ARCH_1 "unknown"
|
||||
#define YQ2ARCH_1 "unknown"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -118,6 +122,14 @@ typedef struct
|
|||
mmove_t *mmovePtr;
|
||||
} mmoveList_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char ver[32];
|
||||
char game[32];
|
||||
char os[32];
|
||||
char arch[32];
|
||||
} savegameHeader_t;
|
||||
|
||||
/* ========================================================= */
|
||||
|
||||
/*
|
||||
|
@ -132,12 +144,12 @@ typedef struct
|
|||
* to each of the functions
|
||||
* prototyped above.
|
||||
*/
|
||||
functionList_t functionList[] = {
|
||||
static functionList_t functionList[] = {
|
||||
#include "tables/gamefunc_list.h"
|
||||
};
|
||||
|
||||
/*
|
||||
* Prtotypes for forward
|
||||
* Prototypes for forward
|
||||
* declaration for all game
|
||||
* mmove_t functions.
|
||||
*/
|
||||
|
@ -149,12 +161,12 @@ functionList_t functionList[] = {
|
|||
* functions prototyped
|
||||
* above.
|
||||
*/
|
||||
mmoveList_t mmoveList[] = {
|
||||
static mmoveList_t mmoveList[] = {
|
||||
#include "tables/gamemmove_list.h"
|
||||
};
|
||||
|
||||
/*
|
||||
* Fields to be saved
|
||||
* Fields to be saved (used in g_spawn.c)
|
||||
*/
|
||||
field_t fields[] = {
|
||||
#include "tables/fields.h"
|
||||
|
@ -164,7 +176,7 @@ field_t fields[] = {
|
|||
* Level fields to
|
||||
* be saved
|
||||
*/
|
||||
field_t levelfields[] = {
|
||||
static field_t levelfields[] = {
|
||||
#include "tables/levelfields.h"
|
||||
};
|
||||
|
||||
|
@ -172,7 +184,7 @@ field_t levelfields[] = {
|
|||
* Client fields to
|
||||
* be saved
|
||||
*/
|
||||
field_t clientfields[] = {
|
||||
static field_t clientfields[] = {
|
||||
#include "tables/clientfields.h"
|
||||
};
|
||||
|
||||
|
@ -187,7 +199,7 @@ void
|
|||
InitGame(void)
|
||||
{
|
||||
gi.dprintf("Game is starting up.\n");
|
||||
gi.dprintf("Game is %s built on %s.\n", GAMEVERSION, __DATE__);
|
||||
gi.dprintf("Game is %s built on %s.\n", GAMEVERSION, BUILD_DATE);
|
||||
|
||||
gun_x = gi.cvar ("gun_x", "0", 0);
|
||||
gun_y = gi.cvar ("gun_y", "0", 0);
|
||||
|
@ -208,15 +220,20 @@ 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);
|
||||
maxspectators = gi.cvar ("maxspectators", "4", CVAR_SERVERINFO);
|
||||
deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH);
|
||||
coop = gi.cvar ("coop", "0", CVAR_LATCH);
|
||||
coop_baseq2 = gi.cvar ("coop_baseq2", "0", CVAR_LATCH);
|
||||
coop_elevator_delay = gi.cvar("coop_elevator_delay", "1.0", CVAR_ARCHIVE);
|
||||
coop_pickup_weapons = gi.cvar("coop_pickup_weapons", "0", CVAR_ARCHIVE);
|
||||
skill = gi.cvar ("skill", "1", CVAR_LATCH);
|
||||
maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH);
|
||||
gamerules = gi.cvar ("gamerules", "0", CVAR_LATCH); //PGM
|
||||
g_footsteps = gi.cvar ("g_footsteps", "1", CVAR_LATCH);
|
||||
g_monsterfootsteps = gi.cvar("g_monsterfootsteps", "0", CVAR_ARCHIVE);
|
||||
g_fix_triggered = gi.cvar ("g_fix_triggered", "0", 0);
|
||||
|
||||
/* change anytime vars */
|
||||
dmflags = gi.cvar ("dmflags", "0", CVAR_SERVERINFO);
|
||||
|
@ -245,6 +262,12 @@ InitGame(void)
|
|||
/* disruptor availability */
|
||||
g_disruptor = gi.cvar ("g_disruptor", "0", 0);
|
||||
|
||||
/* others */
|
||||
aimfix = gi.cvar("aimfix", "0", CVAR_ARCHIVE);
|
||||
g_machinegun_norecoil = gi.cvar("g_machinegun_norecoil", "0", CVAR_ARCHIVE);
|
||||
g_quick_weap = gi.cvar("g_quick_weap", "1", CVAR_ARCHIVE);
|
||||
g_swap_speed = gi.cvar("g_swap_speed", "1", CVAR_ARCHIVE);
|
||||
|
||||
/* items */
|
||||
InitItems ();
|
||||
|
||||
|
@ -761,12 +784,9 @@ ReadClient(FILE *f, gclient_t *client, short save_ver)
|
|||
void
|
||||
WriteGame(const char *filename, qboolean autosave)
|
||||
{
|
||||
savegameHeader_t sv;
|
||||
FILE *f;
|
||||
int i;
|
||||
char str_ver[32];
|
||||
char str_game[32];
|
||||
char str_os[32];
|
||||
char str_arch[32];
|
||||
|
||||
if (!autosave)
|
||||
{
|
||||
|
@ -781,20 +801,14 @@ WriteGame(const char *filename, qboolean autosave)
|
|||
}
|
||||
|
||||
/* Savegame identification */
|
||||
memset(str_ver, 0, sizeof(str_ver));
|
||||
memset(str_game, 0, sizeof(str_game));
|
||||
memset(str_os, 0, sizeof(str_os));
|
||||
memset(str_arch, 0, sizeof(str_arch));
|
||||
memset(&sv, 0, sizeof(sv));
|
||||
|
||||
strncpy(str_ver, SAVEGAMEVER, sizeof(str_ver) - 1);
|
||||
strncpy(str_game, GAMEVERSION, sizeof(str_game) - 1);
|
||||
strncpy(str_os, OSTYPE, sizeof(str_os) - 1);
|
||||
strncpy(str_arch, ARCH, sizeof(str_arch) - 1);
|
||||
Q_strlcpy(sv.ver, SAVEGAMEVER, sizeof(sv.ver) - 1);
|
||||
Q_strlcpy(sv.game, GAMEVERSION, sizeof(sv.game) - 1);
|
||||
Q_strlcpy(sv.os, YQ2OSTYPE, sizeof(sv.os) - 1);
|
||||
Q_strlcpy(sv.arch, YQ2ARCH, sizeof(sv.arch) - 1);
|
||||
|
||||
fwrite(str_ver, sizeof(str_ver), 1, f);
|
||||
fwrite(str_game, sizeof(str_game), 1, f);
|
||||
fwrite(str_os, sizeof(str_os), 1, f);
|
||||
fwrite(str_arch, sizeof(str_arch), 1, f);
|
||||
fwrite(&sv, sizeof(sv), 1, f);
|
||||
|
||||
game.autosaved = autosave;
|
||||
fwrite(&game, sizeof(game), 1, f);
|
||||
|
@ -816,12 +830,10 @@ WriteGame(const char *filename, qboolean autosave)
|
|||
void
|
||||
ReadGame(const char *filename)
|
||||
{
|
||||
savegameHeader_t sv;
|
||||
FILE *f;
|
||||
int i;
|
||||
char str_ver[32];
|
||||
char str_game[32];
|
||||
char str_os[32];
|
||||
char str_arch[32];
|
||||
|
||||
short save_ver = 0;
|
||||
|
||||
gi.FreeTags(TAG_GAME);
|
||||
|
@ -834,89 +846,89 @@ ReadGame(const char *filename)
|
|||
}
|
||||
|
||||
/* Sanity checks */
|
||||
fread(str_ver, sizeof(str_ver), 1, f);
|
||||
fread(str_game, sizeof(str_game), 1, f);
|
||||
fread(str_os, sizeof(str_os), 1, f);
|
||||
fread(str_arch, sizeof(str_arch), 1, f);
|
||||
fread(&sv, sizeof(sv), 1, f);
|
||||
|
||||
if (!strcmp(str_ver, SAVEGAMEVER))
|
||||
static const struct {
|
||||
const char* verstr;
|
||||
int vernum;
|
||||
} version_mappings[] = {
|
||||
{"YQ2-1", 1},
|
||||
{"YQ2-2", 2},
|
||||
{"YQ2-3", 3},
|
||||
{"YQ2-4", 4},
|
||||
{"YQ2-5", 5},
|
||||
{"YQ2-6", 6},
|
||||
};
|
||||
|
||||
for (i=0; i < sizeof(version_mappings)/sizeof(version_mappings[0]); ++i)
|
||||
{
|
||||
save_ver = 4;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
if (strcmp(version_mappings[i].verstr, sv.ver) == 0)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
else if (strcmp(str_arch, ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
save_ver = version_mappings[i].vernum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(str_ver, "YQ2-3"))
|
||||
{
|
||||
save_ver = 3;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
else if (strcmp(str_arch, ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(str_ver, "YQ2-2"))
|
||||
{
|
||||
save_ver = 2;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE_1))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
|
||||
if (!strcmp(str_os, "Windows"))
|
||||
{
|
||||
/* Windows was forced to i386 */
|
||||
if (strcmp(str_arch, "i386"))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(str_arch, ARCH_1))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if(save_ver < 2)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an incompatible version.\n");
|
||||
}
|
||||
else if (save_ver == 2)
|
||||
{
|
||||
if (strcmp(sv.game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(sv.os, YQ2OSTYPE_1))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Windows was forced to i386 */
|
||||
if (strcmp(sv.arch, "i386") != 0)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another architecture.\n");
|
||||
}
|
||||
#else
|
||||
if (strcmp(sv.arch, YQ2ARCH_1) != 0)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another architecture.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else // all newer savegame versions
|
||||
{
|
||||
if (strcmp(sv.game, GAMEVERSION) != 0)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another game.so.\n");
|
||||
}
|
||||
else if (strcmp(sv.os, YQ2OSTYPE) != 0)
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another os.\n");
|
||||
}
|
||||
else if (strcmp(sv.arch, YQ2ARCH) != 0)
|
||||
{
|
||||
#if defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
||||
// before savegame version "YQ2-5" (and after version 2),
|
||||
// the official Win32 binaries accidentally had the YQ2ARCH "AMD64"
|
||||
// instead of "i386" set due to a bug in the Makefile.
|
||||
// This quirk allows loading those savegames anyway
|
||||
if (save_ver >= 5 || strcmp(sv.arch, "AMD64") != 0)
|
||||
#endif
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another architecture.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
|
||||
globals.edicts = g_edicts;
|
||||
|
@ -966,7 +978,7 @@ WriteEdict(FILE *f, edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* Helper fcuntion to write the
|
||||
* Helper function to write the
|
||||
* level local data into a file.
|
||||
* Called by WriteLevel.
|
||||
*/
|
||||
|
@ -1082,10 +1094,10 @@ ReadLevelLocals(FILE *f)
|
|||
|
||||
/*
|
||||
* Reads a level back into the memory.
|
||||
* SpawnEntities were allready called
|
||||
* SpawnEntities were already called
|
||||
* in the same way when the level was
|
||||
* saved. All world links were cleared
|
||||
* befor this function was called. When
|
||||
* before this function was called. When
|
||||
* this function is called, no clients
|
||||
* are connected to the server.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (C) 2011 Yamagi Burmeister
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Prototypes for every function in the game.so.
|
||||
|
@ -34,7 +53,7 @@ extern int Q_strncasecmp ( char * s1 , char * s2 , int n ) ;
|
|||
extern int Q_stricmp ( const char * s1 , const char * s2 ) ;
|
||||
extern void Com_PageInMemory ( byte * buffer , int size ) ;
|
||||
extern char * COM_Parse ( char * * data_p ) ;
|
||||
extern char * va ( char * format , ... ) ;
|
||||
extern char * va ( const char * format , ... ) ;
|
||||
extern void Swap_Init ( void ) ;
|
||||
extern float FloatNoSwap ( float f ) ;
|
||||
extern float FloatSwap ( float f ) ;
|
||||
|
@ -123,7 +142,7 @@ extern void ChangeWeapon ( edict_t * ent ) ;
|
|||
extern qboolean Pickup_Weapon ( edict_t * ent , edict_t * other ) ;
|
||||
extern void PlayerNoise ( edict_t * who , vec3_t where , int type ) ;
|
||||
extern void P_ProjectSource2 ( gclient_t * client , vec3_t point , vec3_t distance , vec3_t forward , vec3_t right , vec3_t up , vec3_t result ) ;
|
||||
extern void P_ProjectSource ( gclient_t * client , vec3_t point , vec3_t distance , vec3_t forward , vec3_t right , vec3_t result ) ;
|
||||
extern void P_ProjectSource(edict_t *ent, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
|
||||
extern byte P_DamageModifier ( edict_t * ent ) ;
|
||||
extern void ClientEndServerFrame ( edict_t * ent ) ;
|
||||
extern void G_SetClientFrame ( edict_t * ent ) ;
|
||||
|
@ -187,7 +206,7 @@ extern void ClientObituary ( edict_t * self , edict_t * inflictor , edict_t * at
|
|||
extern qboolean IsNeutral ( edict_t * ent ) ;
|
||||
extern qboolean IsFemale ( edict_t * ent ) ;
|
||||
extern void player_pain ( edict_t * self , edict_t * other , float kick , int damage ) ;
|
||||
extern void SP_info_player_intermission ( void ) ;
|
||||
extern void SP_info_player_intermission ( edict_t *ent );
|
||||
extern void SP_info_player_coop_lava ( edict_t * self ) ;
|
||||
extern void SP_info_player_coop ( edict_t * self ) ;
|
||||
extern void SP_info_player_deathmatch ( edict_t * self ) ;
|
||||
|
@ -380,6 +399,7 @@ extern void SP_monster_soldier_ss ( edict_t * self ) ;
|
|||
extern void SP_monster_soldier ( edict_t * self ) ;
|
||||
extern void SP_monster_soldier_light ( edict_t * self ) ;
|
||||
extern void SP_monster_soldier_x ( edict_t * self ) ;
|
||||
extern void soldier_footstep( edict_t *self ) ;
|
||||
extern void soldier_blind ( edict_t * self ) ;
|
||||
extern void soldier_duck ( edict_t * self , float eta ) ;
|
||||
extern void soldier_sidestep ( edict_t * self ) ;
|
||||
|
@ -481,11 +501,12 @@ extern void SP_monster_medic ( edict_t * self ) ;
|
|||
extern qboolean medic_blocked ( edict_t *self, float dist ) ;
|
||||
extern void medic_sidestep( edict_t *self ) ;
|
||||
extern void medic_duck( edict_t *self, float eta ) ;
|
||||
extern void medic_footstep( edict_t *self ) ;
|
||||
extern qboolean medic_checkattack ( edict_t * self ) ;
|
||||
extern void medic_finish_spawn ( edict_t *self );
|
||||
extern void medic_spawngrows ( edict_t *self );
|
||||
extern void medic_determine_spawn ( edict_t *self ) ;
|
||||
extern void medic_start_spawn ( edict_t *self ) ;
|
||||
extern void medic_start_spawn ( edict_t *self ) ;
|
||||
extern void medic_attack ( edict_t * self ) ;
|
||||
extern void medic_hook_retract ( edict_t * self ) ;
|
||||
extern void medic_cable_attack ( edict_t * self ) ;
|
||||
|
@ -506,6 +527,7 @@ extern void abortHeal( edict_t *self, qboolean change_frame, qboolean gib, qbool
|
|||
extern qboolean canReach ( edict_t *self, edict_t *other ) ;
|
||||
extern edict_t * medic_FindDeadMonster ( edict_t * self ) ;
|
||||
extern void SP_misc_insane ( edict_t * self ) ;
|
||||
extern void insane_footstep( edict_t *self ) ;
|
||||
extern void insane_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
extern void insane_dead ( edict_t * self ) ;
|
||||
extern void insane_stand ( edict_t * self ) ;
|
||||
|
@ -521,6 +543,7 @@ extern void insane_moan ( edict_t * self ) ;
|
|||
extern void insane_shake ( edict_t * self ) ;
|
||||
extern void insane_fist ( edict_t * self ) ;
|
||||
extern void SP_monster_infantry ( edict_t * self ) ;
|
||||
extern void infantry_footstep( edict_t *self ) ;
|
||||
extern void infantry_sidestep ( edict_t * self ) ;
|
||||
extern void infantry_duck ( edict_t * self , float eta ) ;
|
||||
extern qboolean infantry_blocked ( edict_t * self , float dist ) ;
|
||||
|
@ -559,6 +582,7 @@ extern void hover_reattack ( edict_t * self ) ;
|
|||
extern void hover_search ( edict_t * self ) ;
|
||||
extern void hover_sight ( edict_t * self , edict_t * other ) ;
|
||||
extern void SP_monster_gunner ( edict_t * self ) ;
|
||||
extern void gunner_footstep( edict_t *self ) ;
|
||||
extern void gunner_sidestep ( edict_t * self ) ;
|
||||
extern void gunner_duck ( edict_t * self , float eta ) ;
|
||||
extern qboolean gunner_blocked ( edict_t * self , float dist ) ;
|
||||
|
@ -588,6 +612,7 @@ extern void gunner_sight ( edict_t * self , edict_t * other ) ;
|
|||
extern void gunner_idlesound ( edict_t * self ) ;
|
||||
extern void SP_monster_gladiator ( edict_t * self ) ;
|
||||
qboolean gladiator_blocked ( edict_t *self , float dist ) ;
|
||||
extern void gladiator_footstep( edict_t *self ) ;
|
||||
extern void gladiator_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
extern void gladiator_dead ( edict_t * self ) ;
|
||||
extern void gladiator_pain ( edict_t * self , edict_t * other , float kick , int damage ) ;
|
||||
|
@ -658,6 +683,7 @@ extern void flipper_run ( edict_t * self ) ;
|
|||
extern void flipper_run_loop ( edict_t * self ) ;
|
||||
extern void flipper_stand ( edict_t * self ) ;
|
||||
extern void SP_monster_chick ( edict_t * self ) ;
|
||||
extern void chick_footstep( edict_t *self ) ;
|
||||
extern void chick_sidestep ( edict_t * self ) ;
|
||||
extern void chick_duck ( edict_t * self , float eta ) ;
|
||||
extern qboolean chick_blocked ( edict_t * self , float dist ) ;
|
||||
|
@ -711,6 +737,7 @@ extern void CarrierGrenade ( edict_t * self ) ;
|
|||
extern void CarrierCoopCheck ( edict_t * self ) ;
|
||||
extern void carrier_sight ( edict_t * self , edict_t * other ) ;
|
||||
extern void SP_monster_brain ( edict_t * self ) ;
|
||||
extern void brain_footstep( edict_t *self ) ;
|
||||
extern void brain_duck ( edict_t * self , float eta ) ;
|
||||
extern void brain_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
extern void brain_dead ( edict_t * self ) ;
|
||||
|
@ -735,6 +762,7 @@ extern void SP_monster_makron ( edict_t * self ) ;
|
|||
extern void MakronPrecache ( void ) ;
|
||||
extern qboolean Makron_CheckAttack ( edict_t * self ) ;
|
||||
extern void makron_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
extern void makron_torso_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
extern void makron_dead ( edict_t * self ) ;
|
||||
extern void makron_torso ( edict_t * ent ) ;
|
||||
extern void makron_torso_think ( edict_t * self ) ;
|
||||
|
@ -795,6 +823,7 @@ extern void boss2_firebullet_right ( edict_t * self ) ;
|
|||
extern void Boss2Rocket ( edict_t * self ) ;
|
||||
extern void boss2_search ( edict_t * self ) ;
|
||||
extern void SP_monster_berserk ( edict_t * self ) ;
|
||||
extern void berserk_footstep( edict_t *self ) ;
|
||||
extern void berserk_sidestep ( edict_t * self ) ;
|
||||
extern qboolean berserk_blocked ( edict_t * self , float dist ) ;
|
||||
extern void berserk_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
|
||||
|
@ -927,6 +956,7 @@ extern void SP_target_secret ( edict_t * ent ) ;
|
|||
extern void use_target_secret ( edict_t * ent , edict_t * other , edict_t * activator ) ;
|
||||
extern void SP_target_help ( edict_t * ent ) ;
|
||||
extern void Use_Target_Help ( edict_t * ent , edict_t * other , edict_t * activator ) ;
|
||||
extern void Target_Help_Think ( edict_t * ent );
|
||||
extern void SP_target_speaker ( edict_t * ent ) ;
|
||||
extern void Use_Target_Speaker ( edict_t * ent , edict_t * other , edict_t * activator ) ;
|
||||
extern void SP_target_temp_entity ( edict_t * ent ) ;
|
||||
|
@ -1487,3 +1517,4 @@ extern void DBall_GameInit ( void ) ;
|
|||
extern void DBall_SelectSpawnPoint ( edict_t * ent , vec3_t origin , vec3_t angles ) ;
|
||||
extern void DBall_ClientBegin ( edict_t * ent ) ;
|
||||
extern int DBall_CheckDMRules ( void ) ;
|
||||
extern void wait_and_change_think(edict_t* ent);
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (C) 2011 Yamagi Burmeister
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Functionpointers to every function in the game.so.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
*/
|
||||
|
||||
{"ReadLevel", (byte *)ReadLevel},
|
||||
{"ReadLevelLocals", (byte *)ReadLevelLocals},
|
||||
|
@ -380,6 +399,7 @@
|
|||
{"SP_monster_soldier", (byte *)SP_monster_soldier},
|
||||
{"SP_monster_soldier_light", (byte *)SP_monster_soldier_light},
|
||||
{"SP_monster_soldier_x", (byte *)SP_monster_soldier_x},
|
||||
{"soldier_footstep", (byte *)soldier_footstep},
|
||||
{"soldier_blind", (byte *)soldier_blind},
|
||||
{"soldier_duck", (byte *)soldier_duck},
|
||||
{"soldier_sidestep", (byte *)soldier_sidestep},
|
||||
|
@ -481,6 +501,7 @@
|
|||
{"medic_blocked", (byte *)medic_blocked},
|
||||
{"medic_sidestep", (byte *)medic_sidestep},
|
||||
{"medic_duck", (byte *)medic_duck},
|
||||
{"medic_footstep", (byte *)medic_footstep},
|
||||
{"medic_checkattack", (byte *)medic_checkattack},
|
||||
{"medic_attack", (byte *)medic_attack},
|
||||
{"medic_finish_spawn", (byte *)medic_finish_spawn},
|
||||
|
@ -506,6 +527,7 @@
|
|||
{"canReach", (byte *)canReach},
|
||||
{"medic_FindDeadMonster", (byte *)medic_FindDeadMonster},
|
||||
{"SP_misc_insane", (byte *)SP_misc_insane},
|
||||
{"insane_footstep", (byte *)insane_footstep},
|
||||
{"insane_die", (byte *)insane_die},
|
||||
{"insane_dead", (byte *)insane_dead},
|
||||
{"insane_stand", (byte *)insane_stand},
|
||||
|
@ -521,6 +543,7 @@
|
|||
{"insane_shake", (byte *)insane_shake},
|
||||
{"insane_fist", (byte *)insane_fist},
|
||||
{"SP_monster_infantry", (byte *)SP_monster_infantry},
|
||||
{"infantry_footstep", (byte *)infantry_footstep},
|
||||
{"infantry_sidestep", (byte *)infantry_sidestep},
|
||||
{"infantry_duck", (byte *)infantry_duck},
|
||||
{"infantry_blocked", (byte *)infantry_blocked},
|
||||
|
@ -559,6 +582,7 @@
|
|||
{"hover_search", (byte *)hover_search},
|
||||
{"hover_sight", (byte *)hover_sight},
|
||||
{"SP_monster_gunner", (byte *)SP_monster_gunner},
|
||||
{"gunner_footstep", (byte *)gunner_footstep},
|
||||
{"gunner_sidestep", (byte *)gunner_sidestep},
|
||||
{"gunner_duck", (byte *)gunner_duck},
|
||||
{"gunner_blocked", (byte *)gunner_blocked},
|
||||
|
@ -587,6 +611,7 @@
|
|||
{"gunner_sight", (byte *)gunner_sight},
|
||||
{"gunner_idlesound", (byte *)gunner_idlesound},
|
||||
{"SP_monster_gladiator", (byte *)SP_monster_gladiator},
|
||||
{"gladiator_footstep", (byte *)gladiator_footstep},
|
||||
{"gladiator_blocked", (byte *)gladiator_blocked},
|
||||
{"gladiator_die", (byte *)gladiator_die},
|
||||
{"gladiator_dead", (byte *)gladiator_dead},
|
||||
|
@ -658,6 +683,7 @@
|
|||
{"flipper_run_loop", (byte *)flipper_run_loop},
|
||||
{"flipper_stand", (byte *)flipper_stand},
|
||||
{"SP_monster_chick", (byte *)SP_monster_chick},
|
||||
{"chick_footstep", (byte *)chick_footstep},
|
||||
{"chick_sidestep", (byte *)chick_sidestep},
|
||||
{"chick_duck", (byte *)chick_duck},
|
||||
{"chick_blocked", (byte *)chick_blocked},
|
||||
|
@ -711,6 +737,7 @@
|
|||
{"CarrierCoopCheck", (byte *)CarrierCoopCheck},
|
||||
{"carrier_sight", (byte *)carrier_sight},
|
||||
{"SP_monster_brain", (byte *)SP_monster_brain},
|
||||
{"brain_footstep", (byte *)brain_footstep},
|
||||
{"brain_duck", (byte *)brain_duck},
|
||||
{"brain_die", (byte *)brain_die},
|
||||
{"brain_dead", (byte *)brain_dead},
|
||||
|
@ -735,6 +762,7 @@
|
|||
{"MakronPrecache", (byte *)MakronPrecache},
|
||||
{"Makron_CheckAttack", (byte *)Makron_CheckAttack},
|
||||
{"makron_die", (byte *)makron_die},
|
||||
{"makron_torso_die", (byte *)makron_torso_die},
|
||||
{"makron_dead", (byte *)makron_dead},
|
||||
{"makron_torso", (byte *)makron_torso},
|
||||
{"makron_torso_think", (byte *)makron_torso_think},
|
||||
|
@ -795,6 +823,7 @@
|
|||
{"Boss2Rocket", (byte *)Boss2Rocket},
|
||||
{"boss2_search", (byte *)boss2_search},
|
||||
{"SP_monster_berserk", (byte *)SP_monster_berserk},
|
||||
{"berserk_footstep", (byte *)berserk_footstep},
|
||||
{"berserk_sidestep", (byte *)berserk_sidestep},
|
||||
{"berserk_blocked", (byte *)berserk_blocked},
|
||||
{"berserk_die", (byte *)berserk_die},
|
||||
|
@ -927,6 +956,7 @@
|
|||
{"use_target_secret", (byte *)use_target_secret},
|
||||
{"SP_target_help", (byte *)SP_target_help},
|
||||
{"Use_Target_Help", (byte *)Use_Target_Help},
|
||||
{"Target_Help_Think", (byte *)Target_Help_Think},
|
||||
{"SP_target_speaker", (byte *)SP_target_speaker},
|
||||
{"Use_Target_Speaker", (byte *)Use_Target_Speaker},
|
||||
{"SP_target_temp_entity", (byte *)SP_target_temp_entity},
|
||||
|
@ -1488,4 +1518,5 @@
|
|||
{"DBall_SelectSpawnPoint", (byte *)DBall_SelectSpawnPoint},
|
||||
{"DBall_ClientBegin", (byte *)DBall_ClientBegin},
|
||||
{"DBall_CheckDMRules", (byte *)DBall_CheckDMRules},
|
||||
{"wait_and_change_think", (byte *)wait_and_change_think},
|
||||
{0, 0}
|
||||
|
|
|
@ -503,20 +503,9 @@ VectorNormalize(vec3_t v)
|
|||
vec_t
|
||||
VectorNormalize2(vec3_t v, vec3_t out)
|
||||
{
|
||||
float length, ilength;
|
||||
VectorCopy(v, out);
|
||||
|
||||
length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
length = (float)sqrt(length);
|
||||
|
||||
if (length)
|
||||
{
|
||||
ilength = 1 / length;
|
||||
out[0] = v[0] * ilength;
|
||||
out[1] = v[1] * ilength;
|
||||
out[2] = v[2] * ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
return VectorNormalize(out);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -884,7 +873,7 @@ Swap_Init(void)
|
|||
* need to have varargs versions of all text functions.
|
||||
*/
|
||||
char *
|
||||
va(char *format, ...)
|
||||
va(const char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
@ -1333,7 +1322,7 @@ Info_SetValueForKey(char *s, char *key, char *value)
|
|||
|
||||
Com_sprintf(newi, sizeof(newi), "\\%s\\%s", key, value);
|
||||
|
||||
if (strlen(newi) + strlen(s) > maxsize)
|
||||
if (strlen(newi) + strlen(s) >= maxsize)
|
||||
{
|
||||
Com_Printf("Info string length exceeded\n");
|
||||
return;
|
||||
|
|
6123
stuff/mapfixes/rammo1.ent
Normal file
6123
stuff/mapfixes/rammo1.ent
Normal file
File diff suppressed because it is too large
Load diff
5423
stuff/mapfixes/rbase1.ent
Normal file
5423
stuff/mapfixes/rbase1.ent
Normal file
File diff suppressed because it is too large
Load diff
7436
stuff/mapfixes/rhangar2.ent
Normal file
7436
stuff/mapfixes/rhangar2.ent
Normal file
File diff suppressed because it is too large
Load diff
7107
stuff/mapfixes/rmine1.ent
Normal file
7107
stuff/mapfixes/rmine1.ent
Normal file
File diff suppressed because it is too large
Load diff
5282
stuff/mapfixes/rsewer1.ent
Normal file
5282
stuff/mapfixes/rsewer1.ent
Normal file
File diff suppressed because it is too large
Load diff
6805
stuff/mapfixes/rsewer2.ent
Normal file
6805
stuff/mapfixes/rsewer2.ent
Normal file
File diff suppressed because it is too large
Load diff
8317
stuff/mapfixes/rware2.ent
Normal file
8317
stuff/mapfixes/rware2.ent
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue