mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-25 22:01:01 +00:00
Merge branch 'next' into lua-colorlib
This commit is contained in:
commit
befd9596df
137 changed files with 8908 additions and 8034 deletions
|
@ -1,9 +1,9 @@
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
working_directory: /root/SRB2
|
working_directory: /home/circleci/SRB2
|
||||||
docker:
|
docker:
|
||||||
- image: debian:stretch
|
- image: cimg/base:current
|
||||||
environment:
|
environment:
|
||||||
CC: ccache gcc -m32
|
CC: ccache gcc -m32
|
||||||
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||||
|
@ -11,7 +11,7 @@ jobs:
|
||||||
LIBGME_LDFLAGS: -lgme
|
LIBGME_LDFLAGS: -lgme
|
||||||
CCACHE_COMPRESS: true
|
CCACHE_COMPRESS: true
|
||||||
WFLAGS: -Wno-unsuffixed-float-constants
|
WFLAGS: -Wno-unsuffixed-float-constants
|
||||||
GCC49: true
|
GCC81: true
|
||||||
#- image: ubuntu:trusty
|
#- image: ubuntu:trusty
|
||||||
# environment:
|
# environment:
|
||||||
# CC: ccache gcc -m32
|
# CC: ccache gcc -m32
|
||||||
|
@ -25,39 +25,42 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
name: Add i386 arch
|
name: Add i386 arch
|
||||||
command: dpkg --add-architecture i386
|
command: sudo dpkg --add-architecture i386
|
||||||
- run:
|
- run:
|
||||||
name: Add STJr PPA
|
name: Add STJr PPA
|
||||||
command: |
|
command: |
|
||||||
apt-get -qq update
|
sudo apt-get -qq update
|
||||||
apt-get -qq -y install dirmngr
|
sudo apt-get -qq -y install dirmngr
|
||||||
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6
|
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6
|
||||||
echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" >> /etc/apt/sources.list
|
echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" | sudo tee -a /etc/apt/sources.list
|
||||||
- run:
|
- run:
|
||||||
name: Make APT cache folder
|
name: Make APT cache folder
|
||||||
command: mkdir -p /root/.cache/apt/archives/partial
|
command: mkdir -p /home/circleci/.cache/apt/archives/partial
|
||||||
- run:
|
- run:
|
||||||
name: Make APT cache usage by _apt
|
name: Make APT cache usage by _apt
|
||||||
command: chown -Rv _apt:root /root/.cache/apt/archives/partial
|
command: sudo chown -Rv _apt:root /home/circleci/.cache/apt/archives/partial
|
||||||
- run:
|
- run:
|
||||||
name: Update APT listing
|
name: Update APT listing
|
||||||
command: apt-get -qq update
|
command: sudo apt-get -qq update
|
||||||
- run:
|
- run:
|
||||||
name: Support S3 upload
|
name: Support S3 upload
|
||||||
command: apt-get -qq -y install ca-certificates
|
command: sudo apt-get -qq -y install ca-certificates
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- v1-SRB2-APT
|
- v1-SRB2-APT
|
||||||
- run:
|
- run:
|
||||||
name: Install SDK
|
name: Uninstall amd64 SDK
|
||||||
command: apt-get -o Dir::Cache="/root/.cache/apt" -qq -y --no-install-recommends install git build-essential libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
|
command: sudo apt-get -o Dir::Cache="/home/circleci/.cache/apt" -qq -y --no-install-recommends remove libcurl4-openssl-dev:amd64
|
||||||
|
- run:
|
||||||
|
name: Install i386 SDK
|
||||||
|
command: sudo apt-get -o Dir::Cache="/home/circleci/.cache/apt" -qq -y --no-install-recommends install git build-essential libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
|
||||||
- run:
|
- run:
|
||||||
name: make md5sum
|
name: make md5sum
|
||||||
command: find /root/.cache/apt/archives -type f -print0 | sort -z | xargs -r0 md5sum > /root/.cache/apt_archives.md5
|
command: sudo find /home/circleci/.cache/apt/archives -type f -print0 | sort -z | sudo xargs -r0 md5sum > /home/circleci/.cache/apt_archives.md5
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v1-SRB2-APT-{{ checksum "/root/.cache/apt_archives.md5" }}
|
key: v1-SRB2-APT-{{ checksum "/home/circleci/.cache/apt_archives.md5" }}
|
||||||
paths:
|
paths:
|
||||||
- /root/.cache/apt
|
- /home/circleci/.cache/apt
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Compile without network support
|
name: Compile without network support
|
||||||
|
@ -78,9 +81,9 @@ jobs:
|
||||||
name: Compile
|
name: Compile
|
||||||
command: make -C src LINUX=1 ERRORMODE=1 -k -j4
|
command: make -C src LINUX=1 ERRORMODE=1 -k -j4
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /root/SRB2/bin/
|
path: /home/circleci/SRB2/bin/
|
||||||
destination: bin
|
destination: bin
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v1-SRB2-{{ .Branch }}-{{ checksum "make/linux/SDL.deps" }}
|
key: v1-SRB2-{{ .Branch }}-{{ checksum "make/linux/SDL.deps" }}
|
||||||
paths:
|
paths:
|
||||||
- /root/.ccache
|
- /home/circleci/.ccache
|
||||||
|
|
4
.gitattributes
vendored
4
.gitattributes
vendored
|
@ -1,15 +1,17 @@
|
||||||
#Source code
|
#Source code
|
||||||
|
/Makefile text=auto
|
||||||
/src/*.c text=auto
|
/src/*.c text=auto
|
||||||
/src/*.h text=auto
|
/src/*.h text=auto
|
||||||
/src/*.s text=auto
|
/src/*.s text=auto
|
||||||
/src/*.m text=auto
|
/src/*.m text=auto
|
||||||
/src/*.xpm text=auto
|
/src/*.xpm text=auto
|
||||||
/src/Makefile text=auto
|
/src/Makefile text=auto
|
||||||
|
/tools/Makefile text=auto
|
||||||
/src/Make*.cfg text=auto
|
/src/Make*.cfg text=auto
|
||||||
/src/CMakeLists.txt text=auto
|
/src/CMakeLists.txt text=auto
|
||||||
|
*.mk -whitespace text=auto
|
||||||
# Windows EOL
|
# Windows EOL
|
||||||
*.cs -crlf -whitespace
|
*.cs -crlf -whitespace
|
||||||
*.mk -crlf -whitespace
|
|
||||||
*.bat -crlf -whitespace
|
*.bat -crlf -whitespace
|
||||||
*.dev -crlf -whitespace
|
*.dev -crlf -whitespace
|
||||||
*.dsp -crlf -whitespace
|
*.dsp -crlf -whitespace
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -23,3 +23,4 @@ Win32_LIB_ASM_Release
|
||||||
/bin
|
/bin
|
||||||
/build
|
/build
|
||||||
/build/*
|
/build/*
|
||||||
|
/CMakeUserPresets.json
|
434
.gitlab-ci.yml
Normal file
434
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,434 @@
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: clone
|
||||||
|
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH
|
||||||
|
|
||||||
|
default:
|
||||||
|
image: debian:stable-slim
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG
|
||||||
|
fallback_keys:
|
||||||
|
- cache-$CI_PROJECT_PATH_SLUG-$CI_DEFAULT_BRANCH
|
||||||
|
- cache-$CI_PROJECT_PATH_SLUG-default
|
||||||
|
paths:
|
||||||
|
- ccache
|
||||||
|
- ccache_statslog
|
||||||
|
|
||||||
|
- key: apt-$CI_JOB_IMAGE
|
||||||
|
paths:
|
||||||
|
- apt-cache
|
||||||
|
unprotect: true
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- - |
|
||||||
|
# debconf
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:debconf[collapsed=true]\r\e[0KSetup debconf's environment"
|
||||||
|
- export DEBIAN_FRONTEND="noninteractive"
|
||||||
|
- export DEBIAN_PRIORITY="low"
|
||||||
|
- export DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||||
|
- |
|
||||||
|
# debconf
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:debconf\r\e[0K"
|
||||||
|
- - |
|
||||||
|
# dpkg_aa
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:dpkg_aa[collapsed=true]\r\e[0KAdding architectures to dpkg"
|
||||||
|
- dpkg --add-architecture i386
|
||||||
|
- dpkg --add-architecture amd64
|
||||||
|
- dpkg --add-architecture arm64
|
||||||
|
- |
|
||||||
|
# dpkg_aa
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:dpkg_aa\r\e[0K"
|
||||||
|
- - |
|
||||||
|
# apt_conf
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_conf[collapsed=true]\r\e[0KSetting up APT conf"
|
||||||
|
- export APT_CACHE_DIR=`pwd`/apt-cache
|
||||||
|
- mkdir --parents --verbose $APT_CACHE_DIR/partial/
|
||||||
|
- touch /etc/apt/apt.conf.d/99build
|
||||||
|
- |
|
||||||
|
# apt.conf
|
||||||
|
echo Adding options to apt.conf':'
|
||||||
|
- |
|
||||||
|
# APT::Install-Recommends
|
||||||
|
echo APT::Install-Recommends "false"\; | tee --append /etc/apt/apt.conf.d/99build
|
||||||
|
- |
|
||||||
|
# quit
|
||||||
|
echo quiet "1"\; | tee --append /etc/apt/apt.conf.d/99build
|
||||||
|
- |
|
||||||
|
# APT::Get::Assume-Yes
|
||||||
|
echo APT::Get::Assume-Yes "true"\; | tee --append /etc/apt/apt.conf.d/99build
|
||||||
|
- |
|
||||||
|
# Dir::Cache::Archives
|
||||||
|
echo Dir::Cache::Archives "$APT_CACHE_DIR"\; | tee --append /etc/apt/apt.conf.d/99build
|
||||||
|
- |
|
||||||
|
# apt_conf
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_conf\r\e[0K"
|
||||||
|
- - |
|
||||||
|
# apt_update
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
|
||||||
|
- apt-get update
|
||||||
|
- |
|
||||||
|
# apt_update
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_pre
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_pre[collapsed=true]\r\e[0KInstalling pre packages"
|
||||||
|
- apt-get install apt-utils
|
||||||
|
- |
|
||||||
|
# apt_pre
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_pre\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_upgrade
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
|
||||||
|
- apt-get upgrade
|
||||||
|
- |
|
||||||
|
# apt_update
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_upgrade\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_common
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_common[collapsed=true]\r\e[0KInstalling common packages"
|
||||||
|
- apt-get install make git ccache nasm
|
||||||
|
- |
|
||||||
|
# apt_common
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_common\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# ccache_config
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config"
|
||||||
|
- mkdir --parents --verbose ~/.ccache/
|
||||||
|
- touch ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# cache.conf
|
||||||
|
echo Adding ccache configution option
|
||||||
|
- |
|
||||||
|
# base_dir
|
||||||
|
echo base_dir = $PWD | tee --append ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# cache_dir
|
||||||
|
echo cache_dir = $PWD/ccache | tee --append ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# compiler_check
|
||||||
|
echo compiler_check = content | tee --append ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# stats_log
|
||||||
|
echo stats_log = $PWD/ccache_statslog | tee --append ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# max_size
|
||||||
|
echo max_size = 50M | tee --append ~/.ccache/ccache.conf
|
||||||
|
- |
|
||||||
|
# ccache_config
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# cache_reset
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
|
||||||
|
- ccache --zero-stats
|
||||||
|
- ccache --show-stats
|
||||||
|
- |
|
||||||
|
# ccache_reset
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME_SLUG"
|
||||||
|
|
||||||
|
after_script:
|
||||||
|
- - |
|
||||||
|
# apt_clean
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_clean[collapsed=true]\r\e[0KCleaning of unneeded APT packages"
|
||||||
|
- apt-get autoclean
|
||||||
|
- |
|
||||||
|
# apt_clean
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_clean\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# ccache_stats
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
|
||||||
|
- ccache --show-stats --verbose
|
||||||
|
- ccache --show-log-stats --verbose
|
||||||
|
- |
|
||||||
|
# ccahe_stats
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
|
||||||
|
Debian testing GCC:
|
||||||
|
stage: build
|
||||||
|
image: debian:testing-slim
|
||||||
|
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: gcc
|
||||||
|
LDFLAGS: -Wl,-fuse-ld=gold
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||||
|
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev
|
||||||
|
- |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Windows x86:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
expose_as: "Win32"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win32"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
PREFIX: i686-w64-mingw32
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc-mingw-w64-i686-win32
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Debian stable:amd64:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
expose_as: "Debian amd64"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86-64"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: x86_64-linux-gnu-gcc
|
||||||
|
LDFLAGS: -Wl,-fuse-ld=gold
|
||||||
|
OBJCOPY: x86_64-linux-gnu-objcopy
|
||||||
|
OBJDUMP: x86_64-linux-gnu-objdump
|
||||||
|
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||||
|
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libgme-dev:amd64 libopenmpt-dev:amd64
|
||||||
|
- |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Debian stable:i386:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
expose_as: "Debian i386"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-i686"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: i686-linux-gnu-gcc
|
||||||
|
OBJCOPY: i686-linux-gnu-objcopy
|
||||||
|
OBJDUMP: i686-linux-gnu-objdump
|
||||||
|
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc-i686-linux-gnu || apt-get install gcc
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||||
|
- apt-get install libsdl2-mixer-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libgme-dev:i386 libopenmpt-dev:i386
|
||||||
|
- |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Debian stable:arm64:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
expose_as: "Debian arm64"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-aarch64"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: aarch64-linux-gnu-gcc
|
||||||
|
LDFLAGS: -Wl,-fuse-ld=gold
|
||||||
|
OBJCOPY: aarch64-linux-gnu-objcopy
|
||||||
|
OBJDUMP: aarch64-linux-gnu-objdump
|
||||||
|
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||||
|
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libgme-dev:arm64 libopenmpt-dev:arm64
|
||||||
|
- |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Windows x64:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "bin/"
|
||||||
|
- "src/comptime.h"
|
||||||
|
expose_as: "Win64"
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win64"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
PREFIX: x86_64-w64-mingw32
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install gcc-mingw-w64-x86-64-win32
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Debian stable Clang:
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: clang
|
||||||
|
WFLAGS: -Wno-cast-align
|
||||||
|
CFLAGS: -Wno-cast-align
|
||||||
|
LDFLAGS: -Wl,-fuse-ld=gold
|
||||||
|
|
||||||
|
script:
|
||||||
|
- - |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||||
|
- apt-get install clang
|
||||||
|
- |
|
||||||
|
# apt_toolchain
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||||
|
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev
|
||||||
|
- |
|
||||||
|
# apt_development
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||||
|
|
||||||
|
- - |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||||
|
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
|
||||||
|
- |
|
||||||
|
# make
|
||||||
|
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||||
|
|
||||||
|
Debian testing Clang:
|
||||||
|
extends: Debian stable Clang
|
||||||
|
|
||||||
|
image: debian:testing-slim
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CC: clang
|
||||||
|
WFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
|
||||||
|
CFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
|
||||||
|
LDFLAGS: -Wl,-fuse-ld=gold
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.2.11.{branch}-{build}
|
version: 2.2.13.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -3,12 +3,12 @@ ifdef ComSpec
|
||||||
COMSPEC=$(ComSpec)
|
COMSPEC=$(ComSpec)
|
||||||
endif
|
endif
|
||||||
ifdef COMSPEC
|
ifdef COMSPEC
|
||||||
OBJCOPY=objcopy.exe
|
OBJCOPY?=objcopy.exe
|
||||||
OBJDUMP=objdump.exe
|
OBJDUMP?=objdump.exe
|
||||||
GZIP?=gzip.exe
|
GZIP?=gzip.exe
|
||||||
else
|
else
|
||||||
OBJCOPY=objcopy
|
OBJCOPY?=objcopy
|
||||||
OBJDUMP=objdump
|
OBJDUMP?=objdump
|
||||||
GZIP?=gzip
|
GZIP?=gzip
|
||||||
endif
|
endif
|
||||||
DBGNAME=$(BIN).debug
|
DBGNAME=$(BIN).debug
|
||||||
|
|
|
@ -4367,7 +4367,6 @@ thingtypes
|
||||||
{
|
{
|
||||||
color = 14; // Yellow
|
color = 14; // Yellow
|
||||||
title = "Rings and Weapon Panels";
|
title = "Rings and Weapon Panels";
|
||||||
width = 24;
|
|
||||||
height = 24;
|
height = 24;
|
||||||
flags8height = 24;
|
flags8height = 24;
|
||||||
flags8text = "[8] Float";
|
flags8text = "[8] Float";
|
||||||
|
@ -4377,7 +4376,6 @@ thingtypes
|
||||||
{
|
{
|
||||||
title = "Ring";
|
title = "Ring";
|
||||||
sprite = "RINGA0";
|
sprite = "RINGA0";
|
||||||
width = 16;
|
|
||||||
}
|
}
|
||||||
301
|
301
|
||||||
{
|
{
|
||||||
|
@ -4393,6 +4391,7 @@ thingtypes
|
||||||
{
|
{
|
||||||
title = "Infinity Ring";
|
title = "Infinity Ring";
|
||||||
sprite = "RNGIA0";
|
sprite = "RNGIA0";
|
||||||
|
width = 24;
|
||||||
}
|
}
|
||||||
304
|
304
|
||||||
{
|
{
|
||||||
|
@ -4418,43 +4417,53 @@ thingtypes
|
||||||
{
|
{
|
||||||
title = "CTF Team Ring (Red)";
|
title = "CTF Team Ring (Red)";
|
||||||
sprite = "internal:TRNGA0R";
|
sprite = "internal:TRNGA0R";
|
||||||
width = 16;
|
|
||||||
}
|
}
|
||||||
309
|
309
|
||||||
{
|
{
|
||||||
title = "CTF Team Ring (Blue)";
|
title = "CTF Team Ring (Blue)";
|
||||||
sprite = "internal:TRNGA0B";
|
sprite = "internal:TRNGA0B";
|
||||||
width = 16;
|
|
||||||
}
|
}
|
||||||
330
|
330
|
||||||
{
|
{
|
||||||
title = "Bounce Ring Panel";
|
title = "Bounce Ring Panel";
|
||||||
sprite = "PIKBA0";
|
sprite = "PIKBA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
331
|
331
|
||||||
{
|
{
|
||||||
title = "Rail Ring Panel";
|
title = "Rail Ring Panel";
|
||||||
sprite = "PIKRA0";
|
sprite = "PIKRA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
332
|
332
|
||||||
{
|
{
|
||||||
title = "Automatic Ring Panel";
|
title = "Automatic Ring Panel";
|
||||||
sprite = "PIKAA0";
|
sprite = "PIKAA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
333
|
333
|
||||||
{
|
{
|
||||||
title = "Explosion Ring Panel";
|
title = "Explosion Ring Panel";
|
||||||
sprite = "PIKEA0";
|
sprite = "PIKEA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
334
|
334
|
||||||
{
|
{
|
||||||
title = "Scatter Ring Panel";
|
title = "Scatter Ring Panel";
|
||||||
sprite = "PIKSA0";
|
sprite = "PIKSA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
335
|
335
|
||||||
{
|
{
|
||||||
title = "Grenade Ring Panel";
|
title = "Grenade Ring Panel";
|
||||||
sprite = "PIKGA0";
|
sprite = "PIKGA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4463,7 +4472,7 @@ thingtypes
|
||||||
color = 10; // Light Green
|
color = 10; // Light Green
|
||||||
title = "Other Collectibles";
|
title = "Other Collectibles";
|
||||||
width = 16;
|
width = 16;
|
||||||
height = 32;
|
height = 24;
|
||||||
sort = 1;
|
sort = 1;
|
||||||
sprite = "CEMGA0";
|
sprite = "CEMGA0";
|
||||||
|
|
||||||
|
@ -4529,6 +4538,7 @@ thingtypes
|
||||||
{
|
{
|
||||||
title = "Emerald Hunt Location";
|
title = "Emerald Hunt Location";
|
||||||
sprite = "SHRDA0";
|
sprite = "SHRDA0";
|
||||||
|
height = 32;
|
||||||
flags8height = 24;
|
flags8height = 24;
|
||||||
flags8text = "[8] Float";
|
flags8text = "[8] Float";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1185,7 +1185,7 @@ udmf
|
||||||
{
|
{
|
||||||
color = 14; // Yellow
|
color = 14; // Yellow
|
||||||
title = "Rings and Weapon Panels";
|
title = "Rings and Weapon Panels";
|
||||||
width = 24;
|
width = 16;
|
||||||
height = 24;
|
height = 24;
|
||||||
sprite = "RINGA0";
|
sprite = "RINGA0";
|
||||||
|
|
||||||
|
@ -1193,7 +1193,6 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Ring";
|
title = "Ring";
|
||||||
sprite = "RINGA0";
|
sprite = "RINGA0";
|
||||||
width = 16;
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1227,6 +1226,7 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Infinity Ring";
|
title = "Infinity Ring";
|
||||||
sprite = "RNGIA0";
|
sprite = "RNGIA0";
|
||||||
|
width = 24;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1282,7 +1282,6 @@ udmf
|
||||||
{
|
{
|
||||||
title = "CTF Team Ring (Red)";
|
title = "CTF Team Ring (Red)";
|
||||||
sprite = "internal:TRNGA0R";
|
sprite = "internal:TRNGA0R";
|
||||||
width = 16;
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1294,7 +1293,6 @@ udmf
|
||||||
{
|
{
|
||||||
title = "CTF Team Ring (Blue)";
|
title = "CTF Team Ring (Blue)";
|
||||||
sprite = "internal:TRNGA0B";
|
sprite = "internal:TRNGA0B";
|
||||||
width = 16;
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1306,6 +1304,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Bounce Ring Panel";
|
title = "Bounce Ring Panel";
|
||||||
sprite = "PIKBA0";
|
sprite = "PIKBA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1317,6 +1317,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Rail Ring Panel";
|
title = "Rail Ring Panel";
|
||||||
sprite = "PIKRA0";
|
sprite = "PIKRA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1328,6 +1330,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Automatic Ring Panel";
|
title = "Automatic Ring Panel";
|
||||||
sprite = "PIKAA0";
|
sprite = "PIKAA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1339,6 +1343,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Explosion Ring Panel";
|
title = "Explosion Ring Panel";
|
||||||
sprite = "PIKEA0";
|
sprite = "PIKEA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1350,6 +1356,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Scatter Ring Panel";
|
title = "Scatter Ring Panel";
|
||||||
sprite = "PIKSA0";
|
sprite = "PIKSA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1361,6 +1369,8 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Grenade Ring Panel";
|
title = "Grenade Ring Panel";
|
||||||
sprite = "PIKGA0";
|
sprite = "PIKGA0";
|
||||||
|
width = 24;
|
||||||
|
height = 40;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
@ -1375,7 +1385,7 @@ udmf
|
||||||
color = 10; // Light_Green
|
color = 10; // Light_Green
|
||||||
title = "Other Collectibles";
|
title = "Other Collectibles";
|
||||||
width = 16;
|
width = 16;
|
||||||
height = 32;
|
height = 24;
|
||||||
sort = 1;
|
sort = 1;
|
||||||
sprite = "CEMGA0";
|
sprite = "CEMGA0";
|
||||||
|
|
||||||
|
@ -1445,6 +1455,7 @@ udmf
|
||||||
{
|
{
|
||||||
title = "Emerald Hunt Location";
|
title = "Emerald Hunt Location";
|
||||||
sprite = "SHRDA0";
|
sprite = "SHRDA0";
|
||||||
|
height = 32;
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Float?";
|
title = "Float?";
|
||||||
|
|
|
@ -8,11 +8,7 @@ LOCAL_SRC_FILES := am_map.c \
|
||||||
command.c \
|
command.c \
|
||||||
comptime.c \
|
comptime.c \
|
||||||
console.c \
|
console.c \
|
||||||
d_clisrv.c \
|
|
||||||
d_main.c \
|
d_main.c \
|
||||||
d_net.c \
|
|
||||||
d_netcmd.c \
|
|
||||||
d_netfil.c \
|
|
||||||
dehacked.c \
|
dehacked.c \
|
||||||
f_finale.c \
|
f_finale.c \
|
||||||
f_wipe.c \
|
f_wipe.c \
|
||||||
|
@ -20,7 +16,6 @@ LOCAL_SRC_FILES := am_map.c \
|
||||||
g_game.c \
|
g_game.c \
|
||||||
g_input.c \
|
g_input.c \
|
||||||
hu_stuff.c \
|
hu_stuff.c \
|
||||||
i_tcp.c \
|
|
||||||
info.c \
|
info.c \
|
||||||
lzf.c \
|
lzf.c \
|
||||||
m_argv.c \
|
m_argv.c \
|
||||||
|
@ -32,7 +27,6 @@ LOCAL_SRC_FILES := am_map.c \
|
||||||
m_queue.c \
|
m_queue.c \
|
||||||
m_random.c \
|
m_random.c \
|
||||||
md5.c \
|
md5.c \
|
||||||
mserv.c \
|
|
||||||
p_ceilng.c \
|
p_ceilng.c \
|
||||||
p_enemy.c \
|
p_enemy.c \
|
||||||
p_fab.c \
|
p_fab.c \
|
||||||
|
@ -61,6 +55,7 @@ LOCAL_SRC_FILES := am_map.c \
|
||||||
r_things.c \
|
r_things.c \
|
||||||
s_sound.c \
|
s_sound.c \
|
||||||
screen.c \
|
screen.c \
|
||||||
|
snake.c \
|
||||||
sounds.c \
|
sounds.c \
|
||||||
st_stuff.c \
|
st_stuff.c \
|
||||||
string.c \
|
string.c \
|
||||||
|
|
|
@ -6,10 +6,6 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
||||||
config.h.in
|
config.h.in
|
||||||
string.c
|
string.c
|
||||||
d_main.c
|
d_main.c
|
||||||
d_clisrv.c
|
|
||||||
d_net.c
|
|
||||||
d_netfil.c
|
|
||||||
d_netcmd.c
|
|
||||||
dehacked.c
|
dehacked.c
|
||||||
deh_soc.c
|
deh_soc.c
|
||||||
deh_lua.c
|
deh_lua.c
|
||||||
|
@ -83,12 +79,10 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
||||||
sounds.c
|
sounds.c
|
||||||
w_wad.c
|
w_wad.c
|
||||||
filesrch.c
|
filesrch.c
|
||||||
mserv.c
|
|
||||||
http-mserv.c
|
|
||||||
i_tcp.c
|
|
||||||
lzf.c
|
lzf.c
|
||||||
b_bot.c
|
b_bot.c
|
||||||
u_list.c
|
u_list.c
|
||||||
|
snake.c
|
||||||
lua_script.c
|
lua_script.c
|
||||||
lua_baselib.c
|
lua_baselib.c
|
||||||
lua_mathlib.c
|
lua_mathlib.c
|
||||||
|
@ -150,6 +144,7 @@ set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL
|
||||||
"Compile a development build of SRB2.")
|
"Compile a development build of SRB2.")
|
||||||
|
|
||||||
add_subdirectory(blua)
|
add_subdirectory(blua)
|
||||||
|
add_subdirectory(netcode)
|
||||||
|
|
||||||
# OS macros
|
# OS macros
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
|
|
10
src/Makefile
10
src/Makefile
|
@ -62,7 +62,6 @@
|
||||||
#
|
#
|
||||||
# Netplay incompatible
|
# Netplay incompatible
|
||||||
# --------------------
|
# --------------------
|
||||||
# NONET=1 - Disable online capability.
|
|
||||||
# NOMD5=1 - Disable MD5 checksum (validation tool).
|
# NOMD5=1 - Disable MD5 checksum (validation tool).
|
||||||
# NOPOSTPROCESSING=1 - ?
|
# NOPOSTPROCESSING=1 - ?
|
||||||
# MOBJCONSISTANCY=1 - ??
|
# MOBJCONSISTANCY=1 - ??
|
||||||
|
@ -141,9 +140,9 @@ endif
|
||||||
|
|
||||||
OBJDUMP_OPTS?=--wide --source --line-numbers
|
OBJDUMP_OPTS?=--wide --source --line-numbers
|
||||||
|
|
||||||
OBJCOPY:=$(call Prefix,objcopy)
|
OBJCOPY?=$(call Prefix,objcopy)
|
||||||
OBJDUMP:=$(call Prefix,objdump)
|
OBJDUMP?=$(call Prefix,objdump)
|
||||||
WINDRES:=$(call Prefix,windres)
|
WINDRES?=$(call Prefix,windres)
|
||||||
|
|
||||||
GZIP?=gzip
|
GZIP?=gzip
|
||||||
GZIP_OPTS?=-9 -f -n
|
GZIP_OPTS?=-9 -f -n
|
||||||
|
@ -187,6 +186,7 @@ objdir:=$(makedir)/objs
|
||||||
sources+=\
|
sources+=\
|
||||||
$(call List,Sourcefile)\
|
$(call List,Sourcefile)\
|
||||||
$(call List,blua/Sourcefile)\
|
$(call List,blua/Sourcefile)\
|
||||||
|
$(call List,netcode/Sourcefile)\
|
||||||
|
|
||||||
depends:=$(basename $(filter %.c %.s,$(sources)))
|
depends:=$(basename $(filter %.c %.s,$(sources)))
|
||||||
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
|
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
|
||||||
|
@ -392,4 +392,4 @@ else
|
||||||
@:
|
@:
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.)
|
#$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.)
|
||||||
|
|
|
@ -56,15 +56,18 @@ endif
|
||||||
|
|
||||||
# This must have high to low order.
|
# This must have high to low order.
|
||||||
gcc_versions:=\
|
gcc_versions:=\
|
||||||
102 101\
|
132 131 130\
|
||||||
93 92 91\
|
123 122 121 120\
|
||||||
84 83 82 81\
|
114 113 112 111 110\
|
||||||
75 74 73 72 71\
|
105 104 103 102 101 100\
|
||||||
64 63 62 61\
|
95 94 93 92 91 90\
|
||||||
55 54 53 52 51\
|
85 84 83 82 81 80\
|
||||||
|
75 74 73 72 71 70\
|
||||||
|
64 63 62 61 60\
|
||||||
|
55 54 53 52 51 50\
|
||||||
49 48 47 46 45 44 43 42 41 40
|
49 48 47 46 45 44 43 42 41 40
|
||||||
|
|
||||||
latest_gcc_version:=10.2
|
latest_gcc_version:=13.2
|
||||||
|
|
||||||
# Automatically set version flag, but not if one was
|
# Automatically set version flag, but not if one was
|
||||||
# manually set. And don't bother if this is a clean only
|
# manually set. And don't bother if this is a clean only
|
||||||
|
@ -74,13 +77,18 @@ ifeq (,$(call Wildvar,GCC% destructive))
|
||||||
# can't use $(CC) --version here since that uses argv[0] to display the name
|
# can't use $(CC) --version here since that uses argv[0] to display the name
|
||||||
# also gcc outputs the information to stderr, so I had to do 2>&1
|
# also gcc outputs the information to stderr, so I had to do 2>&1
|
||||||
# this program really doesn't like identifying itself
|
# this program really doesn't like identifying itself
|
||||||
version:=$(shell $(CC) -v 2>&1)
|
shellversion:=$(shell $(CC) -v 2>&1)
|
||||||
|
# Try to remove "-win32"
|
||||||
|
version:=$(subst -win32,.0,$(shellversion))
|
||||||
|
|
||||||
# check if this is in fact GCC
|
# check if this is in fact GCC
|
||||||
ifneq (,$(findstring gcc version,$(version)))
|
ifneq (,$(findstring gcc version,$(version)))
|
||||||
|
|
||||||
# in stark contrast to the name, gcc will give me a nicely formatted version number for free
|
# in stark contrast to the name, gcc will give me a nicely formatted version number for free
|
||||||
version:=$(shell $(CC) -dumpfullversion)
|
shellversion:=$(shell $(CC) -dumpfullversion)
|
||||||
|
|
||||||
|
# Try to remove "-win32"
|
||||||
|
version:=$(subst -win32,.0,$(shellversion))
|
||||||
|
|
||||||
# Turn version into words of major, minor
|
# Turn version into words of major, minor
|
||||||
v:=$(subst ., ,$(version))
|
v:=$(subst ., ,$(version))
|
||||||
|
|
|
@ -1,68 +1,66 @@
|
||||||
#
|
#
|
||||||
# Makefile for feature flags.
|
# Makefile for feature flags.
|
||||||
#
|
#
|
||||||
|
|
||||||
passthru_opts+=\
|
passthru_opts+=\
|
||||||
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||||
HAVE_MINIUPNPC\
|
HAVE_MINIUPNPC\
|
||||||
|
|
||||||
# build with debugging information
|
# build with debugging information
|
||||||
ifdef DEBUGMODE
|
ifdef DEBUGMODE
|
||||||
PACKETDROP=1
|
PACKETDROP=1
|
||||||
opts+=-DPARANOIA -DRANGECHECK
|
opts+=-DPARANOIA -DRANGECHECK
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOHW
|
ifndef NOHW
|
||||||
opts+=-DHWRENDER
|
opts+=-DHWRENDER
|
||||||
sources+=$(call List,hardware/Sourcefile)
|
sources+=$(call List,hardware/Sourcefile)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOMD5
|
ifndef NOMD5
|
||||||
sources+=md5.c
|
sources+=md5.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOZLIB
|
ifndef NOZLIB
|
||||||
ifndef NOPNG
|
ifndef NOPNG
|
||||||
ifdef PNG_PKGCONFIG
|
ifdef PNG_PKGCONFIG
|
||||||
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
|
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
|
||||||
else
|
else
|
||||||
PNG_CONFIG?=$(call Prefix,libpng-config)
|
PNG_CONFIG?=$(call Prefix,libpng-config)
|
||||||
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
|
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
|
||||||
$(if $(PNG_STATIC),--static),,--ldflags))
|
$(if $(PNG_STATIC),--static),,--ldflags))
|
||||||
endif
|
endif
|
||||||
ifdef LINUX
|
ifdef LINUX
|
||||||
opts+=-D_LARGEFILE64_SOURCE
|
opts+=-D_LARGEFILE64_SOURCE
|
||||||
endif
|
endif
|
||||||
opts+=-DHAVE_PNG
|
opts+=-DHAVE_PNG
|
||||||
sources+=apng.c
|
sources+=apng.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NONET
|
ifndef NOCURL
|
||||||
ifndef NOCURL
|
CURLCONFIG?=curl-config
|
||||||
CURLCONFIG?=curl-config
|
$(eval $(call Configure,CURL,$(CURLCONFIG)))
|
||||||
$(eval $(call Configure,CURL,$(CURLCONFIG)))
|
opts+=-DHAVE_CURL
|
||||||
opts+=-DHAVE_CURL
|
endif
|
||||||
endif
|
|
||||||
endif
|
ifdef HAVE_MINIUPNPC
|
||||||
|
libs+=-lminiupnpc
|
||||||
ifdef HAVE_MINIUPNPC
|
endif
|
||||||
libs+=-lminiupnpc
|
|
||||||
endif
|
# (Valgrind is a memory debugger.)
|
||||||
|
ifdef VALGRIND
|
||||||
# (Valgrind is a memory debugger.)
|
VALGRIND_PKGCONFIG?=valgrind
|
||||||
ifdef VALGRIND
|
$(eval $(call Use_pkg_config,VALGRIND))
|
||||||
VALGRIND_PKGCONFIG?=valgrind
|
ZDEBUG=1
|
||||||
$(eval $(call Use_pkg_config,VALGRIND))
|
opts+=-DHAVE_VALGRIND
|
||||||
ZDEBUG=1
|
endif
|
||||||
opts+=-DHAVE_VALGRIND
|
|
||||||
endif
|
default_packages:=\
|
||||||
|
GME/libgme/LIBGME\
|
||||||
default_packages:=\
|
OPENMPT/libopenmpt/LIBOPENMPT\
|
||||||
GME/libgme/LIBGME\
|
ZLIB/zlib\
|
||||||
OPENMPT/libopenmpt/LIBOPENMPT\
|
|
||||||
ZLIB/zlib\
|
$(foreach p,$(default_packages),\
|
||||||
|
$(eval $(call Check_pkg_config,$(p))))
|
||||||
$(foreach p,$(default_packages),\
|
|
||||||
$(eval $(call Check_pkg_config,$(p))))
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ endif
|
||||||
# Tested by Steel, as of release 2.2.8.
|
# Tested by Steel, as of release 2.2.8.
|
||||||
ifdef FREEBSD
|
ifdef FREEBSD
|
||||||
opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD
|
opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD
|
||||||
libs+=-L/usr/X11R6/lib -lipx -lkvm
|
libs+=-L/usr/X11R6/lib -lkvm -lexecinfo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# FIXME: UNTESTED
|
# FIXME: UNTESTED
|
||||||
|
|
|
@ -33,12 +33,10 @@ libs+=-lws2_32
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NONET
|
|
||||||
ifndef MINGW64 # miniupnc is broken with MINGW64
|
ifndef MINGW64 # miniupnc is broken with MINGW64
|
||||||
opts+=-I../libs -DSTATIC_MINIUPNPC
|
opts+=-I../libs -DSTATIC_MINIUPNPC
|
||||||
libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi
|
libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef MINGW64
|
ifndef MINGW64
|
||||||
32=32
|
32=32
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
string.c
|
string.c
|
||||||
d_main.c
|
d_main.c
|
||||||
d_clisrv.c
|
|
||||||
d_net.c
|
|
||||||
d_netfil.c
|
|
||||||
d_netcmd.c
|
|
||||||
dehacked.c
|
dehacked.c
|
||||||
deh_soc.c
|
deh_soc.c
|
||||||
deh_lua.c
|
deh_lua.c
|
||||||
|
@ -77,12 +73,10 @@ s_sound.c
|
||||||
sounds.c
|
sounds.c
|
||||||
w_wad.c
|
w_wad.c
|
||||||
filesrch.c
|
filesrch.c
|
||||||
mserv.c
|
|
||||||
http-mserv.c
|
|
||||||
i_tcp.c
|
|
||||||
lzf.c
|
lzf.c
|
||||||
b_bot.c
|
b_bot.c
|
||||||
u_list.c
|
u_list.c
|
||||||
|
snake.c
|
||||||
lua_script.c
|
lua_script.c
|
||||||
lua_baselib.c
|
lua_baselib.c
|
||||||
lua_mathlib.c
|
lua_mathlib.c
|
||||||
|
|
|
@ -1071,7 +1071,6 @@ static inline void AM_drawPlayers(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiplayer (how??)
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator)
|
if (!playeringame[i] || players[i].spectator)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../i_net.h"
|
#include "../netcode/i_net.h"
|
||||||
|
|
||||||
boolean I_InitNetwork(void)
|
boolean I_InitNetwork(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "../i_system.h"
|
#include "../i_system.h"
|
||||||
#include "../g_game.h"
|
#include "../g_game.h"
|
||||||
#include "../d_netfil.h"
|
#include "../netcode/d_netfil.h"
|
||||||
|
#include "../netcode/net_command.h"
|
||||||
#include "../lua_libs.h"
|
#include "../lua_libs.h"
|
||||||
#include "../byteptr.h"
|
#include "../byteptr.h"
|
||||||
#include "../lua_script.h"
|
#include "../lua_script.h"
|
||||||
|
|
|
@ -28,11 +28,12 @@
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
#include "g_game.h" // for player_names
|
#include "g_game.h" // for player_names
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
|
#include "netcode/net_command.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "d_netfil.h" // findfile
|
#include "netcode/d_netfil.h" // findfile
|
||||||
#include "r_data.h" // Color_cons_t
|
#include "r_data.h" // Color_cons_t
|
||||||
#include "d_main.h" // D_IsPathAllowed
|
#include "d_main.h" // D_IsPathAllowed
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,14 @@
|
||||||
* Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3
|
* Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3
|
||||||
* Last updated 2022 / 03 / 06 - v2.2.10 - main assets
|
* Last updated 2022 / 03 / 06 - v2.2.10 - main assets
|
||||||
* Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3
|
* Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3
|
||||||
|
* Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3
|
||||||
|
* Last updated 2023 / 09 / 09 - v2.2.13 - none
|
||||||
*/
|
*/
|
||||||
#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39"
|
#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39"
|
||||||
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7"
|
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7"
|
||||||
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
|
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
#define ASSET_HASH_PATCH_PK3 "2e69558bce3b9610624549a75e29e19b"
|
#define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
5841
src/d_clisrv.c
5841
src/d_clisrv.c
File diff suppressed because it is too large
Load diff
22
src/d_main.c
22
src/d_main.c
|
@ -34,7 +34,7 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "am_map.h"
|
#include "am_map.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_net.h"
|
#include "netcode/d_net.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
|
@ -56,11 +56,11 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_netfil.h"
|
#include "netcode/d_netfil.h"
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "y_inter.h"
|
#include "y_inter.h"
|
||||||
#include "p_local.h" // chasecam
|
#include "p_local.h" // chasecam
|
||||||
#include "mserv.h" // ms_RoomId
|
#include "netcode/mserv.h" // ms_RoomId
|
||||||
#include "m_misc.h" // screenshot functionality
|
#include "m_misc.h" // screenshot functionality
|
||||||
#include "deh_tables.h" // Dehacked list test
|
#include "deh_tables.h" // Dehacked list test
|
||||||
#include "m_cond.h" // condition initialization
|
#include "m_cond.h" // condition initialization
|
||||||
|
@ -981,6 +981,7 @@ void D_StartTitle(void)
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
memset(&luabanks, 0, sizeof(luabanks));
|
memset(&luabanks, 0, sizeof(luabanks));
|
||||||
lastmaploaded = 0;
|
lastmaploaded = 0;
|
||||||
|
pickedchar = R_SkinAvailable(cv_defaultskin.string);
|
||||||
|
|
||||||
// In case someone exits out at the same time they start a time attack run,
|
// In case someone exits out at the same time they start a time attack run,
|
||||||
// reset modeattacking
|
// reset modeattacking
|
||||||
|
@ -1626,6 +1627,8 @@ void D_SRB2Main(void)
|
||||||
autostart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pickedchar = R_SkinAvailable(cv_defaultskin.string);
|
||||||
|
|
||||||
// user settings come before "+" parameters.
|
// user settings come before "+" parameters.
|
||||||
if (dedicated)
|
if (dedicated)
|
||||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home));
|
COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home));
|
||||||
|
@ -1737,14 +1740,15 @@ void D_SRB2Main(void)
|
||||||
// Prevent warping to nonexistent levels
|
// Prevent warping to nonexistent levels
|
||||||
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
|
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
|
||||||
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap));
|
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap));
|
||||||
// Prevent warping to locked levels
|
|
||||||
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
|
|
||||||
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
|
|
||||||
// lives hell.
|
|
||||||
else if (!dedicated && M_MapLocked(pstartmap, serverGamedata))
|
|
||||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (M_CampaignWarpIsCheat(gametype, pstartmap, serverGamedata))
|
||||||
|
{
|
||||||
|
// If you're warping via command line, you know what you're doing.
|
||||||
|
// No need to I_Error over this.
|
||||||
|
G_SetUsedCheats(false);
|
||||||
|
}
|
||||||
|
|
||||||
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
|
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,8 +277,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
|
||||||
}
|
}
|
||||||
else if (fastncmp("MTF_", word, 4)) {
|
else if (fastncmp("MTF_", word, 4)) {
|
||||||
p = word+4;
|
p = word+4;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; MAPTHINGFLAG_LIST[i]; i++)
|
||||||
if (MAPTHINGFLAG_LIST[i] && fastcmp(p, MAPTHINGFLAG_LIST[i])) {
|
if (fastcmp(p, MAPTHINGFLAG_LIST[i])) {
|
||||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hardware/hw_light.h"
|
#include "hardware/hw_light.h"
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hardware/hw_light.h"
|
#include "hardware/hw_light.h"
|
||||||
|
|
|
@ -4410,11 +4410,12 @@ const char *const MOBJEFLAG_LIST[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const MAPTHINGFLAG_LIST[4] = {
|
const char *const MAPTHINGFLAG_LIST[] = {
|
||||||
"EXTRA", // Extra flag for objects.
|
"EXTRA", // Extra flag for objects.
|
||||||
"OBJECTFLIP", // Reverse gravity flag for objects.
|
"OBJECTFLIP", // Reverse gravity flag for objects.
|
||||||
"OBJECTSPECIAL", // Special flag used with certain objects.
|
"OBJECTSPECIAL", // Special flag used with certain objects.
|
||||||
"AMBUSH" // Deaf monsters/do not react to sound.
|
"AMBUSH", // Deaf monsters/do not react to sound.
|
||||||
|
"ABSOLUTEZ" // Absolute spawn height flag for objects.
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const PLAYERFLAG_LIST[] = {
|
const char *const PLAYERFLAG_LIST[] = {
|
||||||
|
@ -4613,8 +4614,7 @@ const char *COLOR_ENUMS[] = {
|
||||||
// Desaturated
|
// Desaturated
|
||||||
"AETHER", // SKINCOLOR_AETHER,
|
"AETHER", // SKINCOLOR_AETHER,
|
||||||
"SLATE", // SKINCOLOR_SLATE,
|
"SLATE", // SKINCOLOR_SLATE,
|
||||||
"METEORITE", // SKINCOLOR_METEORITE,
|
"MOONSTONE", // SKINCOLOR_MOONSTONE,
|
||||||
"MERCURY", // SKINCOLOR_MERCURY,
|
|
||||||
"BLUEBELL", // SKINCOLOR_BLUEBELL,
|
"BLUEBELL", // SKINCOLOR_BLUEBELL,
|
||||||
"PINK", // SKINCOLOR_PINK,
|
"PINK", // SKINCOLOR_PINK,
|
||||||
"ROSEWOOD", // SKINCOLOR_ROSEWOOD,
|
"ROSEWOOD", // SKINCOLOR_ROSEWOOD,
|
||||||
|
@ -4651,10 +4651,10 @@ const char *COLOR_ENUMS[] = {
|
||||||
"COPPER", // SKINCOLOR_COPPER,
|
"COPPER", // SKINCOLOR_COPPER,
|
||||||
"APRICOT", // SKINCOLOR_APRICOT,
|
"APRICOT", // SKINCOLOR_APRICOT,
|
||||||
"ORANGE", // SKINCOLOR_ORANGE,
|
"ORANGE", // SKINCOLOR_ORANGE,
|
||||||
"PUMPKIN", // SKINCOLOR_PUMPKIN,
|
|
||||||
"RUST", // SKINCOLOR_RUST,
|
"RUST", // SKINCOLOR_RUST,
|
||||||
"GOLD", // SKINCOLOR_GOLD,
|
"TANGERINE", // SKINCOLOR_TANGERINE,
|
||||||
"TOPAZ", // SKINCOLOR_TOPAZ,
|
"TOPAZ", // SKINCOLOR_TOPAZ,
|
||||||
|
"GOLD", // SKINCOLOR_GOLD,
|
||||||
"SANDY", // SKINCOLOR_SANDY,
|
"SANDY", // SKINCOLOR_SANDY,
|
||||||
"GOLDENROD", // SKINCOLOR_GOLDENROD,
|
"GOLDENROD", // SKINCOLOR_GOLDENROD,
|
||||||
"YELLOW", // SKINCOLOR_YELLOW,
|
"YELLOW", // SKINCOLOR_YELLOW,
|
||||||
|
@ -4664,20 +4664,21 @@ const char *COLOR_ENUMS[] = {
|
||||||
"LIME", // SKINCOLOR_LIME,
|
"LIME", // SKINCOLOR_LIME,
|
||||||
"PERIDOT", // SKINCOLOR_PERIDOT,
|
"PERIDOT", // SKINCOLOR_PERIDOT,
|
||||||
"APPLE", // SKINCOLOR_APPLE,
|
"APPLE", // SKINCOLOR_APPLE,
|
||||||
|
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
|
||||||
"CHARTREUSE", // SKINCOLOR_CHARTREUSE,
|
"CHARTREUSE", // SKINCOLOR_CHARTREUSE,
|
||||||
"GREEN", // SKINCOLOR_GREEN,
|
"GREEN", // SKINCOLOR_GREEN,
|
||||||
"FOREST", // SKINCOLOR_FOREST,
|
"FOREST", // SKINCOLOR_FOREST,
|
||||||
"SHAMROCK", // SKINCOLOR_SHAMROCK,
|
"SHAMROCK", // SKINCOLOR_SHAMROCK,
|
||||||
"JADE", // SKINCOLOR_JADE,
|
"JADE", // SKINCOLOR_JADE,
|
||||||
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
|
|
||||||
"MINT", // SKINCOLOR_MINT,
|
"MINT", // SKINCOLOR_MINT,
|
||||||
"MASTER", // SKINCOLOR_MASTER,
|
"MASTER", // SKINCOLOR_MASTER,
|
||||||
"EMERALD", // SKINCOLOR_EMERALD,
|
"EMERALD", // SKINCOLOR_EMERALD,
|
||||||
"BOTTLE", // SKINCOLOR_BOTTLE,
|
|
||||||
"SEAFOAM", // SKINCOLOR_SEAFOAM,
|
"SEAFOAM", // SKINCOLOR_SEAFOAM,
|
||||||
"ISLAND", // SKINCOLOR_ISLAND,
|
"ISLAND", // SKINCOLOR_ISLAND,
|
||||||
|
"BOTTLE", // SKINCOLOR_BOTTLE,
|
||||||
"AQUA", // SKINCOLOR_AQUA,
|
"AQUA", // SKINCOLOR_AQUA,
|
||||||
"TEAL", // SKINCOLOR_TEAL,
|
"TEAL", // SKINCOLOR_TEAL,
|
||||||
|
"OCEAN", // SKINCOLOR_OCEAN,
|
||||||
"WAVE", // SKINCOLOR_WAVE,
|
"WAVE", // SKINCOLOR_WAVE,
|
||||||
"CYAN", // SKINCOLOR_CYAN,
|
"CYAN", // SKINCOLOR_CYAN,
|
||||||
"TURQUOISE", // SKINCOLOR_TURQUOISE,
|
"TURQUOISE", // SKINCOLOR_TURQUOISE,
|
||||||
|
@ -4703,7 +4704,7 @@ const char *COLOR_ENUMS[] = {
|
||||||
"NOBLE", // SKINCOLOR_NOBLE,
|
"NOBLE", // SKINCOLOR_NOBLE,
|
||||||
"FUCHSIA", // SKINCOLOR_FUCHSIA,
|
"FUCHSIA", // SKINCOLOR_FUCHSIA,
|
||||||
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
|
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
|
||||||
"CRYSTAL", // SKINCOLOR_CRYSTAL,
|
"SIBERITE", // SKINCOLOR_SIBERITE,
|
||||||
"MAGENTA", // SKINCOLOR_MAGENTA,
|
"MAGENTA", // SKINCOLOR_MAGENTA,
|
||||||
"NEON", // SKINCOLOR_NEON,
|
"NEON", // SKINCOLOR_NEON,
|
||||||
"VIOLET", // SKINCOLOR_VIOLET,
|
"VIOLET", // SKINCOLOR_VIOLET,
|
||||||
|
@ -4882,7 +4883,7 @@ const char *const MENUTYPES_LIST[] = {
|
||||||
"MP_SERVER",
|
"MP_SERVER",
|
||||||
"MP_CONNECT",
|
"MP_CONNECT",
|
||||||
"MP_ROOM",
|
"MP_ROOM",
|
||||||
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
"MP_PLAYERSETUP",
|
||||||
"MP_SERVER_OPTIONS",
|
"MP_SERVER_OPTIONS",
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
|
|
@ -62,7 +62,7 @@ extern const char *const MOBJTYPE_LIST[];
|
||||||
extern const char *const MOBJFLAG_LIST[];
|
extern const char *const MOBJFLAG_LIST[];
|
||||||
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
|
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
|
||||||
extern const char *const MOBJEFLAG_LIST[];
|
extern const char *const MOBJEFLAG_LIST[];
|
||||||
extern const char *const MAPTHINGFLAG_LIST[4];
|
extern const char *const MAPTHINGFLAG_LIST[];
|
||||||
extern const char *const PLAYERFLAG_LIST[];
|
extern const char *const PLAYERFLAG_LIST[];
|
||||||
extern const char *const GAMETYPERULE_LIST[];
|
extern const char *const GAMETYPERULE_LIST[];
|
||||||
extern const char *const ML_LIST[]; // Linedef flags
|
extern const char *const ML_LIST[]; // Linedef flags
|
||||||
|
|
|
@ -62,6 +62,10 @@ enum
|
||||||
#define MTF_AMBUSH 8
|
#define MTF_AMBUSH 8
|
||||||
|
|
||||||
// Do not use bit five or after, as they are used for object z-offsets.
|
// Do not use bit five or after, as they are used for object z-offsets.
|
||||||
|
// Unless it's exclusive to UDMF.
|
||||||
|
|
||||||
|
// Flag to use Z as absolute spawn height, ignoring the floor and ceiling.
|
||||||
|
#define MTF_ABSOLUTEZ 16
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
@ -211,6 +215,7 @@ typedef struct
|
||||||
UINT8 extrainfo;
|
UINT8 extrainfo;
|
||||||
taglist_t tags;
|
taglist_t tags;
|
||||||
fixed_t scale;
|
fixed_t scale;
|
||||||
|
fixed_t spritexscale, spriteyscale;
|
||||||
INT32 args[NUMMAPTHINGARGS];
|
INT32 args[NUMMAPTHINGARGS];
|
||||||
char *stringargs[NUMMAPTHINGSTRINGARGS];
|
char *stringargs[NUMMAPTHINGSTRINGARGS];
|
||||||
struct mobj_s *mobj;
|
struct mobj_s *mobj;
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define NONET
|
|
||||||
#if !defined (HWRENDER) && !defined (NOHW)
|
#if !defined (HWRENDER) && !defined (NOHW)
|
||||||
#define HWRENDER
|
#define HWRENDER
|
||||||
#endif
|
#endif
|
||||||
|
@ -269,8 +268,7 @@ typedef enum
|
||||||
// Desaturated
|
// Desaturated
|
||||||
SKINCOLOR_AETHER,
|
SKINCOLOR_AETHER,
|
||||||
SKINCOLOR_SLATE,
|
SKINCOLOR_SLATE,
|
||||||
SKINCOLOR_METEORITE,
|
SKINCOLOR_MOONSTONE,
|
||||||
SKINCOLOR_MERCURY,
|
|
||||||
SKINCOLOR_BLUEBELL,
|
SKINCOLOR_BLUEBELL,
|
||||||
SKINCOLOR_PINK,
|
SKINCOLOR_PINK,
|
||||||
SKINCOLOR_ROSEWOOD,
|
SKINCOLOR_ROSEWOOD,
|
||||||
|
@ -307,10 +305,10 @@ typedef enum
|
||||||
SKINCOLOR_COPPER,
|
SKINCOLOR_COPPER,
|
||||||
SKINCOLOR_APRICOT,
|
SKINCOLOR_APRICOT,
|
||||||
SKINCOLOR_ORANGE,
|
SKINCOLOR_ORANGE,
|
||||||
SKINCOLOR_PUMPKIN,
|
|
||||||
SKINCOLOR_RUST,
|
SKINCOLOR_RUST,
|
||||||
SKINCOLOR_GOLD,
|
SKINCOLOR_TANGERINE,
|
||||||
SKINCOLOR_TOPAZ,
|
SKINCOLOR_TOPAZ,
|
||||||
|
SKINCOLOR_GOLD,
|
||||||
SKINCOLOR_SANDY,
|
SKINCOLOR_SANDY,
|
||||||
SKINCOLOR_GOLDENROD,
|
SKINCOLOR_GOLDENROD,
|
||||||
SKINCOLOR_YELLOW,
|
SKINCOLOR_YELLOW,
|
||||||
|
@ -320,20 +318,21 @@ typedef enum
|
||||||
SKINCOLOR_LIME,
|
SKINCOLOR_LIME,
|
||||||
SKINCOLOR_PERIDOT,
|
SKINCOLOR_PERIDOT,
|
||||||
SKINCOLOR_APPLE,
|
SKINCOLOR_APPLE,
|
||||||
|
SKINCOLOR_HEADLIGHT,
|
||||||
SKINCOLOR_CHARTREUSE,
|
SKINCOLOR_CHARTREUSE,
|
||||||
SKINCOLOR_GREEN,
|
SKINCOLOR_GREEN,
|
||||||
SKINCOLOR_FOREST,
|
SKINCOLOR_FOREST,
|
||||||
SKINCOLOR_SHAMROCK,
|
SKINCOLOR_SHAMROCK,
|
||||||
SKINCOLOR_JADE,
|
SKINCOLOR_JADE,
|
||||||
SKINCOLOR_HEADLIGHT,
|
|
||||||
SKINCOLOR_MINT,
|
SKINCOLOR_MINT,
|
||||||
SKINCOLOR_MASTER,
|
SKINCOLOR_MASTER,
|
||||||
SKINCOLOR_EMERALD,
|
SKINCOLOR_EMERALD,
|
||||||
SKINCOLOR_BOTTLE,
|
|
||||||
SKINCOLOR_SEAFOAM,
|
SKINCOLOR_SEAFOAM,
|
||||||
SKINCOLOR_ISLAND,
|
SKINCOLOR_ISLAND,
|
||||||
|
SKINCOLOR_BOTTLE,
|
||||||
SKINCOLOR_AQUA,
|
SKINCOLOR_AQUA,
|
||||||
SKINCOLOR_TEAL,
|
SKINCOLOR_TEAL,
|
||||||
|
SKINCOLOR_OCEAN,
|
||||||
SKINCOLOR_WAVE,
|
SKINCOLOR_WAVE,
|
||||||
SKINCOLOR_CYAN,
|
SKINCOLOR_CYAN,
|
||||||
SKINCOLOR_TURQUOISE,
|
SKINCOLOR_TURQUOISE,
|
||||||
|
@ -359,7 +358,7 @@ typedef enum
|
||||||
SKINCOLOR_NOBLE,
|
SKINCOLOR_NOBLE,
|
||||||
SKINCOLOR_FUCHSIA,
|
SKINCOLOR_FUCHSIA,
|
||||||
SKINCOLOR_BUBBLEGUM,
|
SKINCOLOR_BUBBLEGUM,
|
||||||
SKINCOLOR_CRYSTAL,
|
SKINCOLOR_SIBERITE,
|
||||||
SKINCOLOR_MAGENTA,
|
SKINCOLOR_MAGENTA,
|
||||||
SKINCOLOR_NEON,
|
SKINCOLOR_NEON,
|
||||||
SKINCOLOR_VIOLET,
|
SKINCOLOR_VIOLET,
|
||||||
|
@ -724,7 +723,7 @@ extern int
|
||||||
/// Maintain compatibility with older 2.2 demos
|
/// Maintain compatibility with older 2.2 demos
|
||||||
#define OLD22DEMOCOMPAT
|
#define OLD22DEMOCOMPAT
|
||||||
|
|
||||||
#if defined (HAVE_CURL) && ! defined (NONET)
|
#ifdef HAVE_CURL
|
||||||
#define MASTERSERVER
|
#define MASTERSERVER
|
||||||
#else
|
#else
|
||||||
#undef UPDATE_ALERT
|
#undef UPDATE_ALERT
|
||||||
|
|
|
@ -249,6 +249,7 @@ extern textprompt_t *textprompts[MAX_PROMPTS];
|
||||||
// For the Custom Exit linedef.
|
// For the Custom Exit linedef.
|
||||||
extern INT16 nextmapoverride;
|
extern INT16 nextmapoverride;
|
||||||
extern UINT8 skipstats;
|
extern UINT8 skipstats;
|
||||||
|
extern INT16 nextgametype;
|
||||||
|
|
||||||
extern UINT32 ssspheres; // Total # of spheres in a level
|
extern UINT32 ssspheres; // Total # of spheres in a level
|
||||||
|
|
||||||
|
@ -633,7 +634,7 @@ extern boolean singletics;
|
||||||
// Netgame stuff
|
// Netgame stuff
|
||||||
// =============
|
// =============
|
||||||
|
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
|
|
||||||
extern consvar_t cv_timetic; // display high resolution timer
|
extern consvar_t cv_timetic; // display high resolution timer
|
||||||
extern consvar_t cv_powerupdisplay; // display powerups
|
extern consvar_t cv_powerupdisplay; // display powerups
|
||||||
|
|
|
@ -113,6 +113,15 @@ int endswith (const char *base, const char *tag);
|
||||||
#define HAVE_DOSSTR_FUNCS
|
#define HAVE_DOSSTR_FUNCS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (__APPLE__)
|
||||||
|
#define SRB2_HAVE_STRLCPY
|
||||||
|
#elif defined (__GLIBC_PREREQ)
|
||||||
|
// glibc 2.38: added strlcpy and strlcat to _DEFAULT_SOURCE
|
||||||
|
#if __GLIBC_PREREQ(2, 38)
|
||||||
|
#define SRB2_HAVE_STRLCPY
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_DOSSTR_FUNCS
|
#ifndef HAVE_DOSSTR_FUNCS
|
||||||
int strupr(char *n); // from dosstr.c
|
int strupr(char *n); // from dosstr.c
|
||||||
int strlwr(char *n); // from dosstr.c
|
int strlwr(char *n); // from dosstr.c
|
||||||
|
@ -120,7 +129,7 @@ int strlwr(char *n); // from dosstr.c
|
||||||
|
|
||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef SRB2_HAVE_STRLCPY
|
||||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../i_net.h"
|
#include "../netcode/i_net.h"
|
||||||
|
|
||||||
boolean I_InitNetwork(void)
|
boolean I_InitNetwork(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,13 +14,18 @@ size_t I_GetFreeMem(size_t *total)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_Sleep(UINT32 ms){}
|
void I_Sleep(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
}
|
||||||
|
|
||||||
precise_t I_GetPreciseTime(void) {
|
precise_t I_GetPreciseTime(void)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT64 I_GetPrecisePrecision(void) {
|
UINT64 I_GetPrecisePrecision(void)
|
||||||
|
{
|
||||||
return 1000000;
|
return 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,10 +187,12 @@ const char *I_ClipboardPaste(void)
|
||||||
|
|
||||||
size_t I_GetRandomBytes(char *destination, size_t amount)
|
size_t I_GetRandomBytes(char *destination, size_t amount)
|
||||||
{
|
{
|
||||||
|
(void)destination;
|
||||||
|
(void)amount;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_RegisterSysCommands(void) {}
|
void I_RegisterSysCommands(void){}
|
||||||
|
|
||||||
void I_GetCursorPosition(INT32 *x, INT32 *y)
|
void I_GetCursorPosition(INT32 *x, INT32 *y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
|
@ -1062,12 +1062,14 @@ static const char *credits[] = {
|
||||||
"\"Golden\"",
|
"\"Golden\"",
|
||||||
"Vivian \"toaster\" Grannell",
|
"Vivian \"toaster\" Grannell",
|
||||||
"Julio \"Chaos Zero 64\" Guir",
|
"Julio \"Chaos Zero 64\" Guir",
|
||||||
|
"\"Hanicef\"",
|
||||||
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
|
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
|
||||||
"Kepa \"Nev3r\" Iceta",
|
"Kepa \"Nev3r\" Iceta",
|
||||||
"Thomas \"Shadow Hog\" Igoe",
|
"Thomas \"Shadow Hog\" Igoe",
|
||||||
"Iestyn \"Monster Iestyn\" Jealous",
|
"Iestyn \"Monster Iestyn\" Jealous",
|
||||||
"\"Kaito Sinclaire\"",
|
"\"Kaito Sinclaire\"",
|
||||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||||
|
"\"katsy\"",
|
||||||
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
||||||
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
|
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
|
||||||
"\"LZA\"",
|
"\"LZA\"",
|
||||||
|
@ -1090,6 +1092,7 @@ static const char *credits[] = {
|
||||||
"Ben \"Cue\" Woodford",
|
"Ben \"Cue\" Woodford",
|
||||||
"Lachlan \"Lach\" Wright",
|
"Lachlan \"Lach\" Wright",
|
||||||
"Marco \"mazmazz\" Zafra",
|
"Marco \"mazmazz\" Zafra",
|
||||||
|
"\"Zwip-Zwap Zapony\"",
|
||||||
"",
|
"",
|
||||||
"\1Art",
|
"\1Art",
|
||||||
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
|
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
|
||||||
|
@ -1197,6 +1200,7 @@ static const char *credits[] = {
|
||||||
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
|
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
|
||||||
"Kart Krew",
|
"Kart Krew",
|
||||||
"Alex \"MistaED\" Fuller",
|
"Alex \"MistaED\" Fuller",
|
||||||
|
"Howard Drossin", // Virtual Sonic - Sonic & Knuckles Theme
|
||||||
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
|
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
|
||||||
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
|
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
|
||||||
"Simon \"sirjuddington\" Judd", // SLADE developer
|
"Simon \"sirjuddington\" Judd", // SLADE developer
|
||||||
|
@ -1644,7 +1648,7 @@ void F_GameEvaluationTicker(void)
|
||||||
sparklloop = 0;
|
sparklloop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalecount == 5*TICRATE)
|
if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
|
||||||
{
|
{
|
||||||
serverGamedata->timesBeaten++;
|
serverGamedata->timesBeaten++;
|
||||||
clientGamedata->timesBeaten++;
|
clientGamedata->timesBeaten++;
|
||||||
|
@ -2256,7 +2260,7 @@ void F_InitMenuPresValues(void)
|
||||||
curfadevalue = 16;
|
curfadevalue = 16;
|
||||||
curbgcolor = -1;
|
curbgcolor = -1;
|
||||||
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed;
|
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
|
||||||
curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
|
curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
|
||||||
|
|
||||||
curhidepics = hidetitlepics;
|
curhidepics = hidetitlepics;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
#include "d_netfil.h"
|
#include "netcode/d_netfil.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "m_menu.h" // Addons_option_Onchange
|
#include "m_menu.h" // Addons_option_Onchange
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#define __FILESRCH_H__
|
#define __FILESRCH_H__
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_netfil.h"
|
#include "netcode/d_netfil.h"
|
||||||
#include "m_menu.h" // MAXSTRINGLENGTH
|
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
|
||||||
|
|
167
src/g_demo.c
167
src/g_demo.c
|
@ -15,7 +15,7 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "i_time.h"
|
#include "i_time.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
#include "md5.h" // demo checksums
|
#include "md5.h" // demo checksums
|
||||||
#include "d_netfil.h" // G_CheckDemoExtraFiles
|
#include "netcode/d_netfil.h" // G_CheckDemoExtraFiles
|
||||||
|
|
||||||
boolean timingdemo; // if true, exit with report on completion
|
boolean timingdemo; // if true, exit with report on completion
|
||||||
boolean nodrawers; // for comparative timing purposes
|
boolean nodrawers; // for comparative timing purposes
|
||||||
|
@ -1500,8 +1500,12 @@ void G_BeginRecording(void)
|
||||||
demo_p += 16;
|
demo_p += 16;
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
for (i = 0; i < MAXCOLORNAME && cv_playercolor.string[i]; i++)
|
UINT16 skincolor = players[0].skincolor;
|
||||||
name[i] = cv_playercolor.string[i];
|
if (skincolor >= numskincolors)
|
||||||
|
skincolor = SKINCOLOR_NONE;
|
||||||
|
const char *skincolor_name = skincolors[skincolor].name;
|
||||||
|
for (i = 0; i < MAXCOLORNAME && skincolor_name[i]; i++)
|
||||||
|
name[i] = skincolor_name[i];
|
||||||
for (; i < MAXCOLORNAME; i++)
|
for (; i < MAXCOLORNAME; i++)
|
||||||
name[i] = '\0';
|
name[i] = '\0';
|
||||||
M_Memcpy(demo_p,name,MAXCOLORNAME);
|
M_Memcpy(demo_p,name,MAXCOLORNAME);
|
||||||
|
@ -1617,7 +1621,7 @@ void G_BeginMetal(void)
|
||||||
oldmetal.angle = mo->angle>>24;
|
oldmetal.angle = mo->angle>>24;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void G_LoadDemoExtraFiles(UINT8 **pp)
|
static void G_LoadDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version)
|
||||||
{
|
{
|
||||||
UINT16 totalfiles;
|
UINT16 totalfiles;
|
||||||
char filename[MAX_WADPATH];
|
char filename[MAX_WADPATH];
|
||||||
|
@ -1627,6 +1631,12 @@ static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||||
boolean alreadyloaded;
|
boolean alreadyloaded;
|
||||||
UINT16 i, j;
|
UINT16 i, j;
|
||||||
|
|
||||||
|
if (this_demo_version < 0x0010)
|
||||||
|
{
|
||||||
|
// demo has no file list
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
totalfiles = READUINT16((*pp));
|
totalfiles = READUINT16((*pp));
|
||||||
for (i = 0; i < totalfiles; ++i)
|
for (i = 0; i < totalfiles; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1686,12 +1696,12 @@ static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void G_SkipDemoExtraFiles(UINT8 **pp)
|
static void G_SkipDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version)
|
||||||
{
|
{
|
||||||
UINT16 totalfiles;
|
UINT16 totalfiles;
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
|
|
||||||
if (demoversion < 0x0010)
|
if (this_demo_version < 0x0010)
|
||||||
{
|
{
|
||||||
// demo has no file list
|
// demo has no file list
|
||||||
return;
|
return;
|
||||||
|
@ -1707,7 +1717,7 @@ static void G_SkipDemoExtraFiles(UINT8 **pp)
|
||||||
|
|
||||||
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
||||||
// Enabling quick prevents filesystem checks to see if needed files are available to load.
|
// Enabling quick prevents filesystem checks to see if needed files are available to load.
|
||||||
static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick)
|
static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick, UINT16 this_demo_version)
|
||||||
{
|
{
|
||||||
UINT16 totalfiles, filesloaded, nmusfilecount;
|
UINT16 totalfiles, filesloaded, nmusfilecount;
|
||||||
char filename[MAX_WADPATH];
|
char filename[MAX_WADPATH];
|
||||||
|
@ -1717,7 +1727,7 @@ static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick)
|
||||||
UINT16 i, j;
|
UINT16 i, j;
|
||||||
UINT8 error = DFILE_ERROR_NONE;
|
UINT8 error = DFILE_ERROR_NONE;
|
||||||
|
|
||||||
if (demoversion < 0x0010)
|
if (this_demo_version < 0x0010)
|
||||||
{
|
{
|
||||||
// demo has no file list
|
// demo has no file list
|
||||||
return DFILE_ERROR_NONE;
|
return DFILE_ERROR_NONE;
|
||||||
|
@ -1816,10 +1826,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
UINT8 *buffer,*p;
|
UINT8 *buffer,*p;
|
||||||
UINT8 flags;
|
UINT8 flags;
|
||||||
UINT32 oldtime, newtime, oldscore, newscore;
|
UINT32 oldtime, newtime, oldscore, newscore;
|
||||||
UINT16 oldrings, newrings, oldversion;
|
UINT16 oldrings, newrings, oldversion, newversion;
|
||||||
size_t bufsize ATTRUNUSED;
|
size_t bufsize ATTRUNUSED;
|
||||||
UINT8 c;
|
UINT8 c;
|
||||||
UINT16 s ATTRUNUSED;
|
|
||||||
UINT8 aflags = 0;
|
UINT8 aflags = 0;
|
||||||
|
|
||||||
// load the new file
|
// load the new file
|
||||||
|
@ -1835,15 +1844,15 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
I_Assert(c == VERSION);
|
I_Assert(c == VERSION);
|
||||||
c = READUINT8(p); // SUBVERSION
|
c = READUINT8(p); // SUBVERSION
|
||||||
I_Assert(c == SUBVERSION);
|
I_Assert(c == SUBVERSION);
|
||||||
s = READUINT16(p);
|
newversion = READUINT16(p);
|
||||||
I_Assert(s >= 0x000c);
|
I_Assert(newversion == DEMOVERSION);
|
||||||
p += 16; // demo checksum
|
p += 16; // demo checksum
|
||||||
I_Assert(!memcmp(p, "PLAY", 4));
|
I_Assert(!memcmp(p, "PLAY", 4));
|
||||||
p += 4; // PLAY
|
p += 4; // PLAY
|
||||||
p += 2; // gamemap
|
p += 2; // gamemap
|
||||||
p += 16; // map md5
|
p += 16; // map md5
|
||||||
flags = READUINT8(p); // demoflags
|
flags = READUINT8(p); // demoflags
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p, newversion);
|
||||||
aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK);
|
aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK);
|
||||||
I_Assert(aflags);
|
I_Assert(aflags);
|
||||||
if (flags & DF_RECORDATTACK)
|
if (flags & DF_RECORDATTACK)
|
||||||
|
@ -1882,16 +1891,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
p++; // VERSION
|
p++; // VERSION
|
||||||
p++; // SUBVERSION
|
p++; // SUBVERSION
|
||||||
oldversion = READUINT16(p);
|
oldversion = READUINT16(p);
|
||||||
switch(oldversion) // demoversion
|
if (oldversion < 0x000c || oldversion > DEMOVERSION)
|
||||||
{
|
{
|
||||||
case DEMOVERSION: // latest always supported
|
// too old (or new), cannot support
|
||||||
case 0x000f: // The previous demoversions also supported
|
|
||||||
case 0x000e:
|
|
||||||
case 0x000d: // all that changed between then and now was longer color name
|
|
||||||
case 0x000c:
|
|
||||||
break;
|
|
||||||
// too old, cannot support.
|
|
||||||
default:
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
|
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
|
||||||
Z_Free(buffer);
|
Z_Free(buffer);
|
||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
|
@ -1909,7 +1911,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
p += 2; // gamemap
|
p += 2; // gamemap
|
||||||
p += 16; // mapmd5
|
p += 16; // mapmd5
|
||||||
flags = READUINT8(p);
|
flags = READUINT8(p);
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p, oldversion);
|
||||||
if (!(flags & aflags))
|
if (!(flags & aflags))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname);
|
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname);
|
||||||
|
@ -1964,14 +1966,11 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
lumpnum_t l;
|
lumpnum_t l;
|
||||||
char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname;
|
char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname;
|
||||||
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen;
|
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
|
||||||
pflags_t pflags;
|
pflags_t pflags;
|
||||||
UINT32 randseed, followitem;
|
UINT32 randseed, followitem;
|
||||||
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
|
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
#ifdef OLD22DEMOCOMPAT
|
|
||||||
boolean use_old_demo_vars = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
skin[16] = '\0';
|
skin[16] = '\0';
|
||||||
color[MAXCOLORNAME] = '\0';
|
color[MAXCOLORNAME] = '\0';
|
||||||
|
@ -2030,23 +2029,13 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
subversion = READUINT8(demo_p);
|
subversion = READUINT8(demo_p);
|
||||||
demoversion = READUINT16(demo_p);
|
demoversion = READUINT16(demo_p);
|
||||||
demo_forwardmove_rng = (demoversion < 0x0010);
|
demo_forwardmove_rng = (demoversion < 0x0010);
|
||||||
switch(demoversion)
|
|
||||||
{
|
|
||||||
case 0x000f:
|
|
||||||
case 0x000d:
|
|
||||||
case 0x000e:
|
|
||||||
case DEMOVERSION: // latest always supported
|
|
||||||
cnamelen = MAXCOLORNAME;
|
|
||||||
break;
|
|
||||||
#ifdef OLD22DEMOCOMPAT
|
#ifdef OLD22DEMOCOMPAT
|
||||||
// all that changed between then and now was longer color name
|
if (demoversion < 0x000c || demoversion > DEMOVERSION)
|
||||||
case 0x000c:
|
#else
|
||||||
cnamelen = 16;
|
if (demoversion < 0x000d || demoversion > DEMOVERSION)
|
||||||
use_old_demo_vars = true;
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
// too old, cannot support.
|
{
|
||||||
default:
|
// too old (or new), cannot support
|
||||||
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
||||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||||
|
@ -2074,26 +2063,22 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
demoflags = READUINT8(demo_p);
|
demoflags = READUINT8(demo_p);
|
||||||
|
|
||||||
if (demoversion < 0x0010)
|
if (titledemo)
|
||||||
{
|
|
||||||
; // Don't do anything with files.
|
|
||||||
}
|
|
||||||
else if (titledemo)
|
|
||||||
{
|
{
|
||||||
// Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
// Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||||
G_SkipDemoExtraFiles(&demo_p);
|
G_SkipDemoExtraFiles(&demo_p, demoversion);
|
||||||
}
|
}
|
||||||
else if (demofileoverride == DFILE_OVERRIDE_LOAD)
|
else if (demofileoverride == DFILE_OVERRIDE_LOAD)
|
||||||
{
|
{
|
||||||
G_LoadDemoExtraFiles(&demo_p);
|
G_LoadDemoExtraFiles(&demo_p, demoversion);
|
||||||
}
|
}
|
||||||
else if (demofileoverride == DFILE_OVERRIDE_SKIP)
|
else if (demofileoverride == DFILE_OVERRIDE_SKIP)
|
||||||
{
|
{
|
||||||
G_SkipDemoExtraFiles(&demo_p);
|
G_SkipDemoExtraFiles(&demo_p, demoversion);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT8 error = G_CheckDemoExtraFiles(&demo_p, false);
|
UINT8 error = G_CheckDemoExtraFiles(&demo_p, false, demoversion);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -2177,8 +2162,8 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
demo_p += 16;
|
demo_p += 16;
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
M_Memcpy(color,demo_p,cnamelen);
|
M_Memcpy(color, demo_p, (demoversion < 0x000d) ? 16 : MAXCOLORNAME);
|
||||||
demo_p += cnamelen;
|
demo_p += (demoversion < 0x000d) ? 16 : MAXCOLORNAME;
|
||||||
|
|
||||||
charability = READUINT8(demo_p);
|
charability = READUINT8(demo_p);
|
||||||
charability2 = READUINT8(demo_p);
|
charability2 = READUINT8(demo_p);
|
||||||
|
@ -2214,7 +2199,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
// net var data
|
// net var data
|
||||||
#ifdef OLD22DEMOCOMPAT
|
#ifdef OLD22DEMOCOMPAT
|
||||||
if (use_old_demo_vars)
|
if (demoversion < 0x000d)
|
||||||
CV_LoadOldDemoVars(&demo_p);
|
CV_LoadOldDemoVars(&demo_p);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -2262,7 +2247,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
players[0].skincolor = i;
|
players[0].skincolor = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
|
|
||||||
if (players[0].mo)
|
if (players[0].mo)
|
||||||
{
|
{
|
||||||
players[0].mo->color = players[0].skincolor;
|
players[0].mo->color = players[0].skincolor;
|
||||||
|
@ -2302,6 +2286,13 @@ UINT8 G_CheckDemoForError(char *defdemoname)
|
||||||
{
|
{
|
||||||
lumpnum_t l;
|
lumpnum_t l;
|
||||||
char *n,*pdemoname;
|
char *n,*pdemoname;
|
||||||
|
UINT16 our_demo_version;
|
||||||
|
|
||||||
|
if (titledemo)
|
||||||
|
{
|
||||||
|
// Don't do anything with files for these.
|
||||||
|
return DFILE_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
n = defdemoname+strlen(defdemoname);
|
n = defdemoname+strlen(defdemoname);
|
||||||
while (*n != '/' && *n != '\\' && n != defdemoname)
|
while (*n != '/' && *n != '\\' && n != defdemoname)
|
||||||
|
@ -2340,21 +2331,14 @@ UINT8 G_CheckDemoForError(char *defdemoname)
|
||||||
|
|
||||||
demo_p++; // version
|
demo_p++; // version
|
||||||
demo_p++; // subversion
|
demo_p++; // subversion
|
||||||
demoversion = READUINT16(demo_p);
|
our_demo_version = READUINT16(demo_p);
|
||||||
demo_forwardmove_rng = (demoversion < 0x0010);
|
|
||||||
switch(demoversion)
|
|
||||||
{
|
|
||||||
case 0x000d:
|
|
||||||
case 0x000e:
|
|
||||||
case 0x000f:
|
|
||||||
case DEMOVERSION: // latest always supported
|
|
||||||
break;
|
|
||||||
#ifdef OLD22DEMOCOMPAT
|
#ifdef OLD22DEMOCOMPAT
|
||||||
case 0x000c:
|
if (our_demo_version < 0x000c || our_demo_version > DEMOVERSION)
|
||||||
break;
|
#else
|
||||||
|
if (our_demo_version < 0x000d || our_demo_version > DEMOVERSION)
|
||||||
#endif
|
#endif
|
||||||
// too old, cannot support.
|
{
|
||||||
default:
|
// too old (or new), cannot support
|
||||||
return DFILE_ERROR_NOTDEMO;
|
return DFILE_ERROR_NOTDEMO;
|
||||||
}
|
}
|
||||||
demo_p += 16; // demo checksum
|
demo_p += 16; // demo checksum
|
||||||
|
@ -2368,17 +2352,7 @@ UINT8 G_CheckDemoForError(char *defdemoname)
|
||||||
|
|
||||||
demo_p++; // demoflags
|
demo_p++; // demoflags
|
||||||
|
|
||||||
// Don't do anything with files.
|
return G_CheckDemoExtraFiles(&demo_p, true, our_demo_version);
|
||||||
if (demoversion < 0x0010)
|
|
||||||
{
|
|
||||||
return DFILE_ERROR_NONE;
|
|
||||||
}
|
|
||||||
else if (titledemo)
|
|
||||||
{
|
|
||||||
return DFILE_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return G_CheckDemoExtraFiles(&demo_p, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_AddGhost(char *defdemoname)
|
void G_AddGhost(char *defdemoname)
|
||||||
|
@ -2386,7 +2360,6 @@ void G_AddGhost(char *defdemoname)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
lumpnum_t l;
|
lumpnum_t l;
|
||||||
char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16];
|
char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16];
|
||||||
UINT8 cnamelen;
|
|
||||||
demoghost *gh;
|
demoghost *gh;
|
||||||
UINT8 flags, subversion;
|
UINT8 flags, subversion;
|
||||||
UINT8 *buffer,*p;
|
UINT8 *buffer,*p;
|
||||||
|
@ -2438,20 +2411,9 @@ void G_AddGhost(char *defdemoname)
|
||||||
p++; // VERSION
|
p++; // VERSION
|
||||||
subversion = READUINT8(p); // SUBVERSION
|
subversion = READUINT8(p); // SUBVERSION
|
||||||
ghostversion = READUINT16(p);
|
ghostversion = READUINT16(p);
|
||||||
switch(ghostversion)
|
if (ghostversion < 0x000c || ghostversion > DEMOVERSION)
|
||||||
{
|
{
|
||||||
case 0x000f:
|
// too old (or new), cannot support
|
||||||
case 0x000d:
|
|
||||||
case 0x000e:
|
|
||||||
case DEMOVERSION: // latest always supported
|
|
||||||
cnamelen = MAXCOLORNAME;
|
|
||||||
break;
|
|
||||||
// all that changed between then and now was longer color name
|
|
||||||
case 0x000c:
|
|
||||||
cnamelen = 16;
|
|
||||||
break;
|
|
||||||
// too old, cannot support.
|
|
||||||
default:
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
||||||
Z_Free(pdemoname);
|
Z_Free(pdemoname);
|
||||||
Z_Free(buffer);
|
Z_Free(buffer);
|
||||||
|
@ -2487,7 +2449,7 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
G_SkipDemoExtraFiles(&p, ghostversion); // Don't wanna modify the file list for ghosts.
|
||||||
|
|
||||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
{
|
{
|
||||||
|
@ -2514,8 +2476,8 @@ void G_AddGhost(char *defdemoname)
|
||||||
p += 16;
|
p += 16;
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
M_Memcpy(color, p,cnamelen);
|
M_Memcpy(color, p, (ghostversion < 0x000d) ? 16 : MAXCOLORNAME);
|
||||||
p += cnamelen;
|
p += (ghostversion < 0x000d) ? 16 : MAXCOLORNAME;
|
||||||
|
|
||||||
// Ghosts do not have a player structure to put this in.
|
// Ghosts do not have a player structure to put this in.
|
||||||
p++; // charability
|
p++; // charability
|
||||||
|
@ -2698,16 +2660,9 @@ void G_DoPlayMetal(void)
|
||||||
metal_p++; // VERSION
|
metal_p++; // VERSION
|
||||||
metal_p++; // SUBVERSION
|
metal_p++; // SUBVERSION
|
||||||
metalversion = READUINT16(metal_p);
|
metalversion = READUINT16(metal_p);
|
||||||
switch(metalversion)
|
if (metalversion < 0x000c || metalversion > DEMOVERSION)
|
||||||
{
|
{
|
||||||
case DEMOVERSION: // latest always supported
|
// too old (or new), cannot support
|
||||||
case 0x000f:
|
|
||||||
case 0x000e: // There are checks wheter the momentum is from older demo versions or not
|
|
||||||
case 0x000d: // all that changed between then and now was longer color name
|
|
||||||
case 0x000c:
|
|
||||||
break;
|
|
||||||
// too old, cannot support.
|
|
||||||
default:
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
|
||||||
Z_Free(metalbuffer);
|
Z_Free(metalbuffer);
|
||||||
return;
|
return;
|
||||||
|
|
89
src/g_game.c
89
src/g_game.c
|
@ -15,7 +15,8 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
|
#include "netcode/net_command.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
|
@ -55,6 +56,8 @@ gameaction_t gameaction;
|
||||||
gamestate_t gamestate = GS_NULL;
|
gamestate_t gamestate = GS_NULL;
|
||||||
UINT8 ultimatemode = false;
|
UINT8 ultimatemode = false;
|
||||||
|
|
||||||
|
INT32 pickedchar;
|
||||||
|
|
||||||
boolean botingame;
|
boolean botingame;
|
||||||
UINT8 botskin;
|
UINT8 botskin;
|
||||||
UINT16 botcolor;
|
UINT16 botcolor;
|
||||||
|
@ -156,6 +159,7 @@ textprompt_t *textprompts[MAX_PROMPTS];
|
||||||
|
|
||||||
INT16 nextmapoverride;
|
INT16 nextmapoverride;
|
||||||
UINT8 skipstats;
|
UINT8 skipstats;
|
||||||
|
INT16 nextgametype = -1;
|
||||||
|
|
||||||
// Pointers to each CTF flag
|
// Pointers to each CTF flag
|
||||||
mobj_t *redflag;
|
mobj_t *redflag;
|
||||||
|
@ -315,6 +319,8 @@ consvar_t cv_consolechat = CVAR_INIT ("chatmode", "Window", CV_SAVE, consolechat
|
||||||
// Pause game upon window losing focus
|
// Pause game upon window losing focus
|
||||||
consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL);
|
consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||||
|
|
||||||
|
consvar_t cv_instantretry = CVAR_INIT ("instantretry", "No", CV_SAVE, CV_YesNo, NULL);
|
||||||
|
|
||||||
consvar_t cv_crosshair = CVAR_INIT ("crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL);
|
consvar_t cv_crosshair = CVAR_INIT ("crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL);
|
||||||
consvar_t cv_crosshair2 = CVAR_INIT ("crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL);
|
consvar_t cv_crosshair2 = CVAR_INIT ("crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL);
|
||||||
consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL);
|
consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||||
|
@ -2079,7 +2085,7 @@ boolean G_Responder(event_t *ev)
|
||||||
if (gameaction == ga_nothing && !singledemo &&
|
if (gameaction == ga_nothing && !singledemo &&
|
||||||
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
||||||
{
|
{
|
||||||
if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE))
|
if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0)))
|
||||||
{
|
{
|
||||||
M_StartControlPanel();
|
M_StartControlPanel();
|
||||||
return true;
|
return true;
|
||||||
|
@ -2137,7 +2143,7 @@ boolean G_Responder(event_t *ev)
|
||||||
if (! netgame)
|
if (! netgame)
|
||||||
F_StartGameEvaluation();
|
F_StartGameEvaluation();
|
||||||
else if (server || IsPlayerAdmin(consoleplayer))
|
else if (server || IsPlayerAdmin(consoleplayer))
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2172,9 +2178,9 @@ boolean G_Responder(event_t *ev)
|
||||||
if (menuactive || pausedelay < 0 || leveltime < 2)
|
if (menuactive || pausedelay < 0 || leveltime < 2)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (pausedelay < 1+(NEWTICRATE/2))
|
if (!cv_instantretry.value && pausedelay < 1+(NEWTICRATE/2))
|
||||||
pausedelay = 1+(NEWTICRATE/2);
|
pausedelay = 1+(NEWTICRATE/2);
|
||||||
else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
|
else if (cv_instantretry.value || ++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
|
||||||
{
|
{
|
||||||
G_SetModeAttackRetryFlag();
|
G_SetModeAttackRetryFlag();
|
||||||
return true;
|
return true;
|
||||||
|
@ -2748,25 +2754,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
|
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
|
||||||
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
|
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
|
||||||
|
|
||||||
// Check to make sure their color didn't change somehow...
|
|
||||||
if (G_GametypeHasTeams())
|
|
||||||
{
|
|
||||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
|
||||||
{
|
|
||||||
if (p == &players[consoleplayer])
|
|
||||||
CV_SetValue(&cv_playercolor, skincolor_redteam);
|
|
||||||
else if (p == &players[secondarydisplayplayer])
|
|
||||||
CV_SetValue(&cv_playercolor2, skincolor_redteam);
|
|
||||||
}
|
|
||||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
|
||||||
{
|
|
||||||
if (p == &players[consoleplayer])
|
|
||||||
CV_SetValue(&cv_playercolor, skincolor_blueteam);
|
|
||||||
else if (p == &players[secondarydisplayplayer])
|
|
||||||
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (betweenmaps)
|
if (betweenmaps)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3461,9 +3448,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_SetGametype
|
// Sets a new gametype.
|
||||||
//
|
|
||||||
// Set a new gametype, also setting gametype rules accordingly. Yay!
|
|
||||||
//
|
//
|
||||||
void G_SetGametype(INT16 gtype)
|
void G_SetGametype(INT16 gtype)
|
||||||
{
|
{
|
||||||
|
@ -3861,7 +3846,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
|
||||||
for (ix = 0; ix < NUMMAPS; ix++)
|
for (ix = 0; ix < NUMMAPS; ix++)
|
||||||
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
|
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
|
||||||
&& ix != pprevmap // Don't pick the same map.
|
&& ix != pprevmap // Don't pick the same map.
|
||||||
&& (dedicated || !M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
|
&& (!M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
|
||||||
)
|
)
|
||||||
okmaps[numokmaps++] = ix;
|
okmaps[numokmaps++] = ix;
|
||||||
|
|
||||||
|
@ -4053,6 +4038,13 @@ static void G_DoCompleted(void)
|
||||||
nextmap = 1100-1; // No infinite loop for you
|
nextmap = 1100-1; // No infinite loop for you
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT16 gametype_to_use;
|
||||||
|
|
||||||
|
if (nextgametype >= 0 && nextgametype < gametypecount)
|
||||||
|
gametype_to_use = nextgametype;
|
||||||
|
else
|
||||||
|
gametype_to_use = gametype;
|
||||||
|
|
||||||
// If nextmap is actually going to get used, make sure it points to
|
// If nextmap is actually going to get used, make sure it points to
|
||||||
// a map of the proper gametype -- skip levels that don't support
|
// a map of the proper gametype -- skip levels that don't support
|
||||||
// the current gametype. (Helps avoid playing boss levels in Race,
|
// the current gametype. (Helps avoid playing boss levels in Race,
|
||||||
|
@ -4061,8 +4053,8 @@ static void G_DoCompleted(void)
|
||||||
{
|
{
|
||||||
if (nextmap >= 0 && nextmap < NUMMAPS)
|
if (nextmap >= 0 && nextmap < NUMMAPS)
|
||||||
{
|
{
|
||||||
register INT16 cm = nextmap;
|
INT16 cm = nextmap;
|
||||||
UINT32 tolflag = G_TOLFlag(gametype);
|
UINT32 tolflag = G_TOLFlag(gametype_to_use);
|
||||||
UINT8 visitedmap[(NUMMAPS+7)/8];
|
UINT8 visitedmap[(NUMMAPS+7)/8];
|
||||||
|
|
||||||
memset(visitedmap, 0, sizeof (visitedmap));
|
memset(visitedmap, 0, sizeof (visitedmap));
|
||||||
|
@ -4117,7 +4109,7 @@ static void G_DoCompleted(void)
|
||||||
{
|
{
|
||||||
token--;
|
token--;
|
||||||
|
|
||||||
if (!nextmapoverride)
|
// if (!nextmapoverride) // Having a token should pull the player into the special stage before going to the overridden map (Issue #933)
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 7; i++)
|
||||||
if (!(emeralds & (1<<i)))
|
if (!(emeralds & (1<<i)))
|
||||||
{
|
{
|
||||||
|
@ -4142,7 +4134,7 @@ static void G_DoCompleted(void)
|
||||||
if (cv_advancemap.value == 0) // Stay on same map.
|
if (cv_advancemap.value == 0) // Stay on same map.
|
||||||
nextmap = prevmap;
|
nextmap = prevmap;
|
||||||
else if (cv_advancemap.value == 2) // Go to random map.
|
else if (cv_advancemap.value == 2) // Go to random map.
|
||||||
nextmap = RandMap(G_TOLFlag(gametype), prevmap);
|
nextmap = RandMap(G_TOLFlag(gametype_to_use), prevmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are committed to this map now.
|
// We are committed to this map now.
|
||||||
|
@ -4151,7 +4143,6 @@ static void G_DoCompleted(void)
|
||||||
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
|
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
|
||||||
P_AllocMapHeader(nextmap);
|
P_AllocMapHeader(nextmap);
|
||||||
|
|
||||||
// If the current gametype has no intermission screen set, then don't start it.
|
|
||||||
Y_DetermineIntermissionType();
|
Y_DetermineIntermissionType();
|
||||||
|
|
||||||
if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none))
|
if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none))
|
||||||
|
@ -4217,12 +4208,21 @@ static void G_DoWorldDone(void)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
|
INT16 gametype_to_use;
|
||||||
|
|
||||||
|
if (nextgametype >= 0 && nextgametype < gametypecount)
|
||||||
|
gametype_to_use = nextgametype;
|
||||||
|
else
|
||||||
|
gametype_to_use = gametype;
|
||||||
|
|
||||||
if (gametyperules & GTR_CAMPAIGN)
|
if (gametyperules & GTR_CAMPAIGN)
|
||||||
// don't reset player between maps
|
// don't reset player between maps
|
||||||
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
|
D_MapChange(nextmap+1, gametype_to_use, ultimatemode, false, 0, false, false);
|
||||||
else
|
else
|
||||||
// resetplayer in match/chaos/tag/CTF/race for more equality
|
// resetplayer in match/chaos/tag/CTF/race for more equality
|
||||||
D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false);
|
D_MapChange(nextmap+1, gametype_to_use, ultimatemode, true, 0, false, false);
|
||||||
|
|
||||||
|
nextgametype = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
|
@ -4789,12 +4789,9 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||||
Z_Free(savebuffer);
|
Z_Free(savebuffer);
|
||||||
save_p = savebuffer = NULL;
|
save_p = savebuffer = NULL;
|
||||||
|
|
||||||
// gameaction = ga_nothing;
|
|
||||||
// G_SetGamestate(GS_LEVEL);
|
|
||||||
displayplayer = consoleplayer;
|
displayplayer = consoleplayer;
|
||||||
multiplayer = splitscreen = false;
|
multiplayer = splitscreen = false;
|
||||||
|
|
||||||
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
|
|
||||||
if (setsizeneeded)
|
if (setsizeneeded)
|
||||||
R_ExecuteSetViewSize();
|
R_ExecuteSetViewSize();
|
||||||
|
|
||||||
|
@ -4987,9 +4984,9 @@ cleanup:
|
||||||
// Can be called by the startup code or the menu task,
|
// Can be called by the startup code or the menu task,
|
||||||
// consoleplayer, displayplayer, playeringame[] should be set.
|
// consoleplayer, displayplayer, playeringame[] should be set.
|
||||||
//
|
//
|
||||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
|
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS)
|
||||||
{
|
{
|
||||||
UINT16 color = skins[pickedchar].prefcolor;
|
pickedchar = character;
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
if (demoplayback)
|
if (demoplayback)
|
||||||
|
@ -5010,10 +5007,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
|
||||||
SplitScreen_OnChange();
|
SplitScreen_OnChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
color = skins[pickedchar].prefcolor;
|
SetPlayerSkinByNum(consoleplayer, character);
|
||||||
SetPlayerSkinByNum(consoleplayer, pickedchar);
|
|
||||||
CV_StealthSet(&cv_skin, skins[pickedchar].name);
|
|
||||||
CV_StealthSetValue(&cv_playercolor, color);
|
|
||||||
|
|
||||||
if (mapname)
|
if (mapname)
|
||||||
D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pultmode, true, 1, false, FLS);
|
D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pultmode, true, 1, false, FLS);
|
||||||
|
@ -5093,6 +5087,10 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
CV_StealthSetValue(&cv_itemfinder, 0);
|
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore each player's skin if it was previously forced to be a specific one
|
||||||
|
// (Looks a bit silly, but it works.)
|
||||||
|
boolean reset_skin = netgame && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0';
|
||||||
|
|
||||||
// internal game map
|
// internal game map
|
||||||
// well this check is useless because it is done before (d_netcmd.c::command_map_f)
|
// well this check is useless because it is done before (d_netcmd.c::command_map_f)
|
||||||
// but in case of for demos....
|
// but in case of for demos....
|
||||||
|
@ -5120,6 +5118,9 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
automapactive = false;
|
automapactive = false;
|
||||||
imcontinuing = false;
|
imcontinuing = false;
|
||||||
|
|
||||||
|
if (reset_skin)
|
||||||
|
D_SendPlayerConfig();
|
||||||
|
|
||||||
// fetch saved data if available
|
// fetch saved data if available
|
||||||
if (savedata.lives > 0)
|
if (savedata.lives > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,8 @@ extern boolean promptactive;
|
||||||
|
|
||||||
extern consvar_t cv_pauseifunfocused;
|
extern consvar_t cv_pauseifunfocused;
|
||||||
|
|
||||||
|
extern consvar_t cv_instantretry;
|
||||||
|
|
||||||
// used in game menu
|
// used in game menu
|
||||||
extern consvar_t cv_tutorialprompt;
|
extern consvar_t cv_tutorialprompt;
|
||||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||||
|
@ -174,8 +176,7 @@ void G_SpawnPlayer(INT32 playernum);
|
||||||
|
|
||||||
// Can be called by the startup code or M_Responder.
|
// Can be called by the startup code or M_Responder.
|
||||||
// A normal game starts at map 1, but a warp test can start elsewhere
|
// A normal game starts at map 1, but a warp test can start elsewhere
|
||||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
|
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS);
|
||||||
boolean SSSG, boolean FLS);
|
|
||||||
void G_DoLoadLevel(boolean resetplayer);
|
void G_DoLoadLevel(boolean resetplayer);
|
||||||
void G_StartTitleCard(void);
|
void G_StartTitleCard(void);
|
||||||
void G_PreLevelTitleCard(void);
|
void G_PreLevelTitleCard(void);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "g_input.h"
|
#include "g_input.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "hu_stuff.h" // need HUFONT start & end
|
#include "hu_stuff.h" // need HUFONT start & end
|
||||||
#include "d_net.h"
|
#include "netcode/d_net.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
||||||
|
|
|
@ -53,9 +53,11 @@ typedef enum
|
||||||
|
|
||||||
extern gamestate_t gamestate;
|
extern gamestate_t gamestate;
|
||||||
extern UINT8 titlemapinaction;
|
extern UINT8 titlemapinaction;
|
||||||
extern UINT8 ultimatemode; // was sk_insane
|
extern UINT8 ultimatemode;
|
||||||
extern gameaction_t gameaction;
|
extern gameaction_t gameaction;
|
||||||
|
|
||||||
|
extern INT32 pickedchar;
|
||||||
|
|
||||||
extern boolean botingame;
|
extern boolean botingame;
|
||||||
extern UINT8 botskin;
|
extern UINT8 botskin;
|
||||||
extern UINT16 botcolor;
|
extern UINT16 botcolor;
|
||||||
|
|
|
@ -42,10 +42,10 @@ int unsortedVertexArrayAllocSize = 65536;
|
||||||
// Call HWR_RenderBatches to render all the collected geometry.
|
// Call HWR_RenderBatches to render all the collected geometry.
|
||||||
void HWR_StartBatching(void)
|
void HWR_StartBatching(void)
|
||||||
{
|
{
|
||||||
if (currently_batching)
|
if (currently_batching)
|
||||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||||
|
|
||||||
// init arrays if that has not been done yet
|
// init arrays if that has not been done yet
|
||||||
if (!finalVertexArray)
|
if (!finalVertexArray)
|
||||||
{
|
{
|
||||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||||
|
@ -55,7 +55,7 @@ void HWR_StartBatching(void)
|
||||||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||||
}
|
}
|
||||||
|
|
||||||
currently_batching = true;
|
currently_batching = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
|
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "../r_patch.h"
|
#include "../r_patch.h"
|
||||||
#include "../r_picformats.h"
|
#include "../r_picformats.h"
|
||||||
#include "../r_bsp.h"
|
#include "../r_bsp.h"
|
||||||
#include "../d_clisrv.h"
|
#include "../netcode/d_clisrv.h"
|
||||||
#include "../w_wad.h"
|
#include "../w_wad.h"
|
||||||
#include "../z_zone.h"
|
#include "../z_zone.h"
|
||||||
#include "../r_splats.h"
|
#include "../r_splats.h"
|
||||||
|
@ -1699,7 +1699,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
||||||
{
|
{
|
||||||
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
|
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
|
||||||
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
|
Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl_frontsector->numlights)
|
if (gl_frontsector->numlights)
|
||||||
|
@ -1822,7 +1822,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
||||||
{
|
{
|
||||||
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
|
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
|
||||||
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
|
Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl_backsector->numlights)
|
if (gl_backsector->numlights)
|
||||||
|
@ -3095,7 +3095,7 @@ static void HWR_Subsector(size_t num)
|
||||||
false,
|
false,
|
||||||
*rover->bottomheight,
|
*rover->bottomheight,
|
||||||
*gl_frontsector->lightlist[light].lightlevel,
|
*gl_frontsector->lightlist[light].lightlevel,
|
||||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector,
|
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||||
false, *gl_frontsector->lightlist[light].extra_colormap);
|
false, *gl_frontsector->lightlist[light].extra_colormap);
|
||||||
}
|
}
|
||||||
|
@ -3141,7 +3141,7 @@ static void HWR_Subsector(size_t num)
|
||||||
true,
|
true,
|
||||||
*rover->topheight,
|
*rover->topheight,
|
||||||
*gl_frontsector->lightlist[light].lightlevel,
|
*gl_frontsector->lightlist[light].lightlevel,
|
||||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector,
|
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||||
false, *gl_frontsector->lightlist[light].extra_colormap);
|
false, *gl_frontsector->lightlist[light].extra_colormap);
|
||||||
}
|
}
|
||||||
|
@ -3595,7 +3595,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
floordiff = abs((flip < 0 ? thing->height : 0) + interp.z - groundz);
|
floordiff = abs((flip < 0 ? interp.height : 0) + interp.z - groundz);
|
||||||
|
|
||||||
alpha = floordiff / (4*FRACUNIT) + 75;
|
alpha = floordiff / (4*FRACUNIT) + 75;
|
||||||
if (alpha >= 255) return;
|
if (alpha >= 255) return;
|
||||||
|
@ -3606,9 +3606,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||||
HWR_GetPatch(gpatch);
|
HWR_GetPatch(gpatch);
|
||||||
|
|
||||||
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
||||||
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
|
scalemul = FixedMul(scalemul, (interp.radius*2) / gpatch->height);
|
||||||
if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs
|
|
||||||
scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale));
|
|
||||||
|
|
||||||
fscale = FIXED_TO_FLOAT(scalemul);
|
fscale = FIXED_TO_FLOAT(scalemul);
|
||||||
fx = FIXED_TO_FLOAT(interp.x);
|
fx = FIXED_TO_FLOAT(interp.x);
|
||||||
|
@ -3720,7 +3718,7 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts
|
||||||
|
|
||||||
if (P_MobjFlip(spr->mobj) == -1)
|
if (P_MobjFlip(spr->mobj) == -1)
|
||||||
{
|
{
|
||||||
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
basey = FIXED_TO_FLOAT(interp.z + interp.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4055,32 +4053,32 @@ static void HWR_DrawBoundingBox(gl_vissprite_t *vis)
|
||||||
// repeat this 4 times (overhead)
|
// repeat this 4 times (overhead)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// 17 20 21 11
|
// 15 16 17 09
|
||||||
// 16 15 14 10
|
// 14 13 12 08
|
||||||
// 27 22 *--* 07 12
|
// 23 18 *--* 07 10
|
||||||
// | |
|
// | |
|
||||||
// 26 23 *--* 06 13
|
// 22 19 *--* 06 11
|
||||||
// 24 00 01 02
|
// 20 00 01 02
|
||||||
// 25 05 04 03
|
// 21 05 04 03
|
||||||
//
|
//
|
||||||
|
|
||||||
v[000].x = v[005].x = v[015].x = v[016].x = v[017].x = v[020].x =
|
v[ 0].x = v[ 5].x = v[13].x = v[14].x = v[15].x = v[16].x =
|
||||||
v[022].x = v[023].x = v[024].x = v[025].x = v[026].x = v[027].x = vis->x1; // west
|
v[18].x = v[19].x = v[20].x = v[21].x = v[22].x = v[23].x = vis->x1; // west
|
||||||
|
|
||||||
v[001].x = v[002].x = v[003].x = v[004].x = v[006].x = v[007].x =
|
v[ 1].x = v[ 2].x = v[ 3].x = v[ 4].x = v[ 6].x = v[ 7].x =
|
||||||
v[010].x = v[011].x = v[012].x = v[013].x = v[014].x = v[021].x = vis->x2; // east
|
v[ 8].x = v[ 9].x = v[10].x = v[11].x = v[12].x = v[17].x = vis->x2; // east
|
||||||
|
|
||||||
v[000].z = v[001].z = v[002].z = v[003].z = v[004].z = v[005].z =
|
v[ 0].z = v[ 1].z = v[ 2].z = v[ 3].z = v[ 4].z = v[ 5].z =
|
||||||
v[006].z = v[013].z = v[023].z = v[024].z = v[025].z = v[026].z = vis->z1; // south
|
v[ 6].z = v[11].z = v[19].z = v[20].z = v[21].z = v[22].z = vis->z1; // south
|
||||||
|
|
||||||
v[007].z = v[010].z = v[011].z = v[012].z = v[014].z = v[015].z =
|
v[ 7].z = v[ 8].z = v[ 9].z = v[10].z = v[12].z = v[13].z =
|
||||||
v[016].z = v[017].z = v[020].z = v[021].z = v[022].z = v[027].z = vis->z2; // north
|
v[14].z = v[15].z = v[16].z = v[17].z = v[18].z = v[23].z = vis->z2; // north
|
||||||
|
|
||||||
v[000].y = v[001].y = v[002].y = v[006].y = v[007].y = v[010].y =
|
v[ 0].y = v[ 1].y = v[ 2].y = v[ 6].y = v[ 7].y = v[ 8].y =
|
||||||
v[014].y = v[015].y = v[016].y = v[022].y = v[023].y = v[024].y = vis->gz; // bottom
|
v[12].y = v[13].y = v[14].y = v[18].y = v[19].y = v[20].y = vis->gz; // bottom
|
||||||
|
|
||||||
v[003].y = v[004].y = v[005].y = v[011].y = v[012].y = v[013].y =
|
v[ 3].y = v[ 4].y = v[ 5].y = v[ 9].y = v[10].y = v[11].y =
|
||||||
v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top
|
v[15].y = v[16].y = v[17].y = v[21].y = v[22].y = v[23].y = vis->gzt; // top
|
||||||
|
|
||||||
Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj));
|
Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj));
|
||||||
|
|
||||||
|
@ -4143,14 +4141,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||||
float xscale, yscale;
|
float xscale, yscale;
|
||||||
float xoffset, yoffset;
|
float xoffset, yoffset;
|
||||||
float leftoffset, topoffset;
|
float leftoffset, topoffset;
|
||||||
float scale = spr->scale;
|
|
||||||
float zoffset = (P_MobjFlip(spr->mobj) * 0.05f);
|
float zoffset = (P_MobjFlip(spr->mobj) * 0.05f);
|
||||||
pslope_t *splatslope = NULL;
|
pslope_t *splatslope = NULL;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
renderflags_t renderflags = spr->renderflags;
|
renderflags_t renderflags = spr->renderflags;
|
||||||
if (renderflags & RF_SHADOWEFFECTS)
|
|
||||||
scale *= spr->shadowscale;
|
|
||||||
|
|
||||||
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
|
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
|
||||||
angle = spr->mobj->angle;
|
angle = spr->mobj->angle;
|
||||||
|
@ -5326,7 +5321,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
groundz = R_GetShadowZ(thing, NULL);
|
groundz = R_GetShadowZ(thing, NULL);
|
||||||
floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + casterinterp.z - groundz);
|
floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? casterinterp.height : 0) + casterinterp.z - groundz);
|
||||||
|
|
||||||
shadowheight = FIXED_TO_FLOAT(floordiff);
|
shadowheight = FIXED_TO_FLOAT(floordiff);
|
||||||
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
|
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
|
||||||
|
@ -5378,7 +5373,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
if (vflip)
|
if (vflip)
|
||||||
{
|
{
|
||||||
gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
gz = FIXED_TO_FLOAT(interp.z + interp.height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||||
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5684,7 +5679,6 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
|
||||||
gl_vissprite_t *vis;
|
gl_vissprite_t *vis;
|
||||||
float tr_x, tr_y;
|
float tr_x, tr_y;
|
||||||
float tz;
|
float tz;
|
||||||
float rad;
|
|
||||||
|
|
||||||
if (!thing)
|
if (!thing)
|
||||||
return;
|
return;
|
||||||
|
@ -5719,15 +5713,13 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
|
||||||
tr_x += gl_viewx;
|
tr_x += gl_viewx;
|
||||||
tr_y += gl_viewy;
|
tr_y += gl_viewy;
|
||||||
|
|
||||||
rad = FIXED_TO_FLOAT(thing->radius);
|
|
||||||
|
|
||||||
vis = HWR_NewVisSprite();
|
vis = HWR_NewVisSprite();
|
||||||
vis->x1 = tr_x - rad;
|
vis->x1 = tr_x - FIXED_TO_FLOAT(interp.radius);
|
||||||
vis->x2 = tr_x + rad;
|
vis->x2 = tr_x + FIXED_TO_FLOAT(interp.radius);
|
||||||
vis->z1 = tr_y - rad;
|
vis->z1 = tr_y - FIXED_TO_FLOAT(interp.radius);
|
||||||
vis->z2 = tr_y + rad;
|
vis->z2 = tr_y + FIXED_TO_FLOAT(interp.radius);
|
||||||
vis->gz = FIXED_TO_FLOAT(interp.z);
|
vis->gz = FIXED_TO_FLOAT(interp.z);
|
||||||
vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height);
|
vis->gzt = vis->gz + FIXED_TO_FLOAT(interp.height);
|
||||||
vis->mobj = thing;
|
vis->mobj = thing;
|
||||||
|
|
||||||
vis->precip = false;
|
vis->precip = false;
|
||||||
|
|
|
@ -486,7 +486,7 @@ void HWR_InitModels(void)
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 s;
|
INT32 s;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char name[24], filename[32];
|
char name[26], filename[32];
|
||||||
float scale, offset;
|
float scale, offset;
|
||||||
size_t prefixlen;
|
size_t prefixlen;
|
||||||
|
|
||||||
|
@ -585,7 +585,7 @@ modelfound:
|
||||||
void HWR_AddPlayerModel(int skin) // For skins that were added after startup
|
void HWR_AddPlayerModel(int skin) // For skins that were added after startup
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char name[24], filename[32];
|
char name[26], filename[32];
|
||||||
float scale, offset;
|
float scale, offset;
|
||||||
size_t prefixlen;
|
size_t prefixlen;
|
||||||
|
|
||||||
|
@ -644,7 +644,7 @@ void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after s
|
||||||
// name[24] is used to check for names in the models.dat file that match with sprites or player skins
|
// name[24] is used to check for names in the models.dat file that match with sprites or player skins
|
||||||
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
|
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
|
||||||
// PLAYERMODELPREFIX is 6 characters long
|
// PLAYERMODELPREFIX is 6 characters long
|
||||||
char name[24], filename[32];
|
char name[26], filename[32];
|
||||||
float scale, offset;
|
float scale, offset;
|
||||||
|
|
||||||
if (nomd2s)
|
if (nomd2s)
|
||||||
|
@ -1582,7 +1582,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
|
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
|
||||||
|
|
||||||
if (flip)
|
if (flip)
|
||||||
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
p.z = FIXED_TO_FLOAT(interp.z + interp.height);
|
||||||
else
|
else
|
||||||
p.z = FIXED_TO_FLOAT(interp.z);
|
p.z = FIXED_TO_FLOAT(interp.z);
|
||||||
|
|
||||||
|
@ -1618,8 +1618,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
p.roll = true;
|
p.roll = true;
|
||||||
|
|
||||||
// rotation pivot
|
// rotation pivot
|
||||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2);
|
p.centerx = FIXED_TO_FLOAT(interp.radius / 2);
|
||||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
|
p.centery = FIXED_TO_FLOAT(interp.height / 2);
|
||||||
|
|
||||||
// rotation axes relative to camera
|
// rotation axes relative to camera
|
||||||
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||||
|
|
|
@ -672,6 +672,9 @@ void GeneratePolygonNormals(model_t *model, int ztag)
|
||||||
|
|
||||||
for (k = 0; k < mesh->numTriangles; k++)
|
for (k = 0; k < mesh->numTriangles; k++)
|
||||||
{
|
{
|
||||||
|
/// TODO: normalize vectors
|
||||||
|
(void)vertices;
|
||||||
|
(void)polyNormals;
|
||||||
// Vector::Normal(vertices, polyNormals);
|
// Vector::Normal(vertices, polyNormals);
|
||||||
vertices += 3 * 3;
|
vertices += 3 * 3;
|
||||||
polyNormals++;
|
polyNormals++;
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#include "m_cond.h" // emblems
|
#include "m_cond.h" // emblems
|
||||||
#include "m_misc.h" // word jumping
|
#include "m_misc.h" // word jumping
|
||||||
|
|
||||||
#include "d_clisrv.h"
|
#include "netcode/d_clisrv.h"
|
||||||
|
#include "netcode/net_command.h"
|
||||||
|
#include "netcode/gamestate.h"
|
||||||
|
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "g_input.h"
|
#include "g_input.h"
|
||||||
|
@ -175,14 +177,12 @@ static huddrawlist_h luahuddrawlist_scores;
|
||||||
|
|
||||||
static tic_t resynch_ticker = 0;
|
static tic_t resynch_ticker = 0;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// just after
|
// just after
|
||||||
static void Command_Say_f(void);
|
static void Command_Say_f(void);
|
||||||
static void Command_Sayto_f(void);
|
static void Command_Sayto_f(void);
|
||||||
static void Command_Sayteam_f(void);
|
static void Command_Sayteam_f(void);
|
||||||
static void Command_CSay_f(void);
|
static void Command_CSay_f(void);
|
||||||
static void Got_Saycmd(UINT8 **p, INT32 playernum);
|
static void Got_Saycmd(UINT8 **p, INT32 playernum);
|
||||||
#endif
|
|
||||||
|
|
||||||
void HU_LoadGraphics(void)
|
void HU_LoadGraphics(void)
|
||||||
{
|
{
|
||||||
|
@ -327,13 +327,11 @@ void HU_LoadGraphics(void)
|
||||||
//
|
//
|
||||||
void HU_Init(void)
|
void HU_Init(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
COM_AddCommand("say", Command_Say_f, COM_LUA);
|
COM_AddCommand("say", Command_Say_f, COM_LUA);
|
||||||
COM_AddCommand("sayto", Command_Sayto_f, COM_LUA);
|
COM_AddCommand("sayto", Command_Sayto_f, COM_LUA);
|
||||||
COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA);
|
COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA);
|
||||||
COM_AddCommand("csay", Command_CSay_f, COM_LUA);
|
COM_AddCommand("csay", Command_CSay_f, COM_LUA);
|
||||||
RegisterNetXCmd(XD_SAY, Got_Saycmd);
|
RegisterNetXCmd(XD_SAY, Got_Saycmd);
|
||||||
#endif
|
|
||||||
|
|
||||||
// set shift translation table
|
// set shift translation table
|
||||||
shiftxform = english_shiftxform;
|
shiftxform = english_shiftxform;
|
||||||
|
@ -363,8 +361,6 @@ void HU_Start(void)
|
||||||
// EXECUTION
|
// EXECUTION
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM
|
// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM
|
||||||
|
|
||||||
static UINT32 chat_nummsg_log = 0;
|
static UINT32 chat_nummsg_log = 0;
|
||||||
|
@ -412,11 +408,9 @@ static void HU_removeChatText_Log(void)
|
||||||
}
|
}
|
||||||
chat_nummsg_log--; // lost 1 msg.
|
chat_nummsg_log--; // lost 1 msg.
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void HU_AddChatText(const char *text, boolean playsound)
|
void HU_AddChatText(const char *text, boolean playsound)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat.
|
if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat.
|
||||||
S_StartSound(NULL, sfx_radio);
|
S_StartSound(NULL, sfx_radio);
|
||||||
// reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game.
|
// reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game.
|
||||||
|
@ -438,14 +432,8 @@ void HU_AddChatText(const char *text, boolean playsound)
|
||||||
CONS_Printf("%s\n", text);
|
CONS_Printf("%s\n", text);
|
||||||
else // if we aren't, still save the message to log.txt
|
else // if we aren't, still save the message to log.txt
|
||||||
CON_LogMessage(va("%s\n", text));
|
CON_LogMessage(va("%s\n", text));
|
||||||
#else
|
|
||||||
(void)playsound;
|
|
||||||
CONS_Printf("%s\n", text);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
/** Runs a say command, sending an ::XD_SAY message.
|
/** Runs a say command, sending an ::XD_SAY message.
|
||||||
* A say command consists of a signed 8-bit integer for the target, an
|
* A say command consists of a signed 8-bit integer for the target, an
|
||||||
* unsigned 8-bit flag variable, and then the message itself.
|
* unsigned 8-bit flag variable, and then the message itself.
|
||||||
|
@ -865,8 +853,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
void HU_Ticker(void)
|
void HU_Ticker(void)
|
||||||
|
@ -882,7 +868,6 @@ void HU_Ticker(void)
|
||||||
else
|
else
|
||||||
hu_showscores = false;
|
hu_showscores = false;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
if (chat_on)
|
if (chat_on)
|
||||||
{
|
{
|
||||||
// count down the scroll timer.
|
// count down the scroll timer.
|
||||||
|
@ -910,7 +895,6 @@ void HU_Ticker(void)
|
||||||
HU_removeChatText_Mini();
|
HU_removeChatText_Mini();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cechotimer > 0) --cechotimer;
|
if (cechotimer > 0) --cechotimer;
|
||||||
|
|
||||||
|
@ -918,8 +902,6 @@ void HU_Ticker(void)
|
||||||
resynch_ticker++;
|
resynch_ticker++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
static boolean teamtalk = false;
|
static boolean teamtalk = false;
|
||||||
static boolean justscrolleddown;
|
static boolean justscrolleddown;
|
||||||
static boolean justscrolledup;
|
static boolean justscrolledup;
|
||||||
|
@ -1027,8 +1009,6 @@ static void HU_sendChatMessage(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void HU_clearChatChars(void)
|
void HU_clearChatChars(void)
|
||||||
{
|
{
|
||||||
memset(w_chat, '\0', sizeof(w_chat));
|
memset(w_chat, '\0', sizeof(w_chat));
|
||||||
|
@ -1043,9 +1023,7 @@ void HU_clearChatChars(void)
|
||||||
//
|
//
|
||||||
boolean HU_Responder(event_t *ev)
|
boolean HU_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
INT32 c=0;
|
INT32 c=0;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ev->type != ev_keydown)
|
if (ev->type != ev_keydown)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1072,7 +1050,6 @@ boolean HU_Responder(event_t *ev)
|
||||||
return false;
|
return false;
|
||||||
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
|
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
c = (INT32)ev->key;
|
c = (INT32)ev->key;
|
||||||
|
|
||||||
if (!chat_on)
|
if (!chat_on)
|
||||||
|
@ -1222,7 +1199,6 @@ boolean HU_Responder(event_t *ev)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1232,8 +1208,6 @@ boolean HU_Responder(event_t *ev)
|
||||||
// HEADS UP DRAWING
|
// HEADS UP DRAWING
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
// Precompile a wordwrapped string to any given width.
|
// Precompile a wordwrapped string to any given width.
|
||||||
// This is a muuuch better method than V_WORDWRAP.
|
// This is a muuuch better method than V_WORDWRAP.
|
||||||
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
||||||
|
@ -1813,7 +1787,6 @@ static void HU_DrawChat_Old(void)
|
||||||
if (hu_tick < 4)
|
if (hu_tick < 4)
|
||||||
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
|
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Draw crosshairs at the exact center of the view.
|
// Draw crosshairs at the exact center of the view.
|
||||||
// In splitscreen, crosshairs are stretched vertically to compensate for V_PERPLAYER squishing them.
|
// In splitscreen, crosshairs are stretched vertically to compensate for V_PERPLAYER squishing them.
|
||||||
|
@ -1953,7 +1926,6 @@ static void HU_DrawDemoInfo(void)
|
||||||
//
|
//
|
||||||
void HU_Drawer(void)
|
void HU_Drawer(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
// draw chat string plus cursor
|
// draw chat string plus cursor
|
||||||
if (chat_on)
|
if (chat_on)
|
||||||
{
|
{
|
||||||
|
@ -1970,7 +1942,6 @@ void HU_Drawer(void)
|
||||||
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
|
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
|
||||||
HU_drawMiniChat(); // draw messages in a cool fashion.
|
HU_drawMiniChat(); // draw messages in a cool fashion.
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cechotimer)
|
if (cechotimer)
|
||||||
HU_DrawCEcho();
|
HU_DrawCEcho();
|
||||||
|
@ -2025,7 +1996,7 @@ void HU_Drawer(void)
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text);
|
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modeattacking && pausedelay > 0 && !pausebreakkey)
|
if (modeattacking && pausedelay > 0 && !(pausebreakkey || cv_instantretry.value))
|
||||||
{
|
{
|
||||||
INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3);
|
INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3);
|
||||||
INT32 y = hudinfo[HUD_LIVES].y - 13;
|
INT32 y = hudinfo[HUD_LIVES].y - 13;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
||||||
|
|
92
src/info.c
92
src/info.c
|
@ -7194,7 +7194,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD1, // speed
|
EMERALD1, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7220,7 +7220,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD2, // speed
|
EMERALD2, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7246,7 +7246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD3, // speed
|
EMERALD3, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7272,7 +7272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD4, // speed
|
EMERALD4, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7298,7 +7298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD5, // speed
|
EMERALD5, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7324,7 +7324,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD6, // speed
|
EMERALD6, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7350,7 +7350,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_cgot, // deathsound
|
sfx_cgot, // deathsound
|
||||||
EMERALD7, // speed
|
EMERALD7, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -18344,7 +18344,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_bouncering, // mass
|
pw_bouncering, // mass
|
||||||
|
@ -18371,7 +18371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_railring, // mass
|
pw_railring, // mass
|
||||||
|
@ -18425,7 +18425,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_automaticring, // mass
|
pw_automaticring, // mass
|
||||||
|
@ -18452,7 +18452,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_explosionring, // mass
|
pw_explosionring, // mass
|
||||||
|
@ -18479,7 +18479,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_scatterring, // mass
|
pw_scatterring, // mass
|
||||||
|
@ -18506,7 +18506,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_itemup, // deathsound
|
sfx_itemup, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_grenadering, // mass
|
pw_grenadering, // mass
|
||||||
|
@ -18535,7 +18535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_bouncering, // mass
|
pw_bouncering, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -18562,7 +18562,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_railring, // mass
|
pw_railring, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -18589,7 +18589,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_automaticring, // mass
|
pw_automaticring, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -18616,7 +18616,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_explosionring, // mass
|
pw_explosionring, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -18643,7 +18643,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_scatterring, // mass
|
pw_scatterring, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -18670,7 +18670,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_ncitem, // deathsound
|
sfx_ncitem, // deathsound
|
||||||
60*FRACUNIT, // speed
|
60*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
pw_grenadering, // mass
|
pw_grenadering, // mass
|
||||||
2*TICRATE, // damage
|
2*TICRATE, // damage
|
||||||
|
@ -21584,10 +21584,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||||
{"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK
|
{"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK
|
||||||
|
|
||||||
// Desaturated
|
// Desaturated
|
||||||
{"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER
|
{"Aether", {0x00, 0x00, 0x01, 0x01, 0x90, 0x90, 0x91, 0x91, 0x92, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xae}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER
|
||||||
{"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE
|
{"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE
|
||||||
{"Meteorite", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_METEORITE
|
{"Moonstone", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_MOONSTONE
|
||||||
{"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY
|
|
||||||
{"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL
|
{"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL
|
||||||
{"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK
|
{"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK
|
||||||
{"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD
|
{"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD
|
||||||
|
@ -21597,37 +21596,37 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||||
{"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER
|
{"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER
|
||||||
{"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE
|
{"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE
|
||||||
{"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA
|
{"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA
|
||||||
{"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU
|
{"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_ARCTIC, 12, V_BROWNMAP, true}, // SKINCOLOR_ECRU
|
||||||
{"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN
|
{"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN
|
||||||
{"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE
|
{"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE
|
||||||
{"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH
|
{"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH
|
||||||
{"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS
|
{"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS
|
||||||
{"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE
|
{"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE
|
||||||
{"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT
|
{"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT
|
||||||
{"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
|
{"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
|
||||||
|
|
||||||
// Viv's vivid colours (toast 21/07/17)
|
// Viv's vivid colours (toast 21/07/17)
|
||||||
// Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22)
|
// Tweaks & additions (Lach, Chrispy, sphere, Alice, MotorRoach & Saneko 26/10/22)
|
||||||
{"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY
|
{"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY
|
||||||
{"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY
|
{"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY
|
||||||
{"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON
|
{"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON
|
||||||
{"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_PEPPER
|
{"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_PEPPER
|
||||||
{"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_RED
|
{"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED
|
||||||
{"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON
|
{"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON
|
||||||
{"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME
|
{"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME
|
||||||
{"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 6, V_REDMAP, true}, // SKINCOLOR_GARNET
|
{"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 6, V_REDMAP, true}, // SKINCOLOR_GARNET
|
||||||
{"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP
|
{"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP
|
||||||
{"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY
|
{"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY
|
||||||
{"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL
|
{"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL
|
||||||
{"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION
|
{"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 197, 186, 187, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION
|
||||||
{"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET
|
{"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET
|
||||||
{"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER
|
{"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER
|
||||||
{"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT
|
{"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT
|
||||||
{"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE
|
{"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE
|
||||||
{"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 12, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN
|
|
||||||
{"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST
|
{"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST
|
||||||
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLD
|
{"Tangerine", { 81, 83, 64, 64, 51, 52, 53, 54, 56, 58, 60, 61, 63, 45, 46, 47}, SKINCOLOR_OCEAN, 12, V_ORANGEMAP, true}, // SKINCOLOR_TANGERINE
|
||||||
{"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_METEORITE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ
|
{"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_MOONSTONE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ
|
||||||
|
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD
|
||||||
{"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY
|
{"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY
|
||||||
{"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD
|
{"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD
|
||||||
{"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW
|
{"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW
|
||||||
|
@ -21637,20 +21636,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||||
{"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME
|
{"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME
|
||||||
{"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT
|
{"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT
|
||||||
{"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE
|
{"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE
|
||||||
|
{"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT
|
||||||
{"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE
|
{"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE
|
||||||
{"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_GREEN
|
{"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN
|
||||||
{"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST
|
{"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST
|
||||||
{"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_CRYSTAL, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK
|
{"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_SIBERITE, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK
|
||||||
{"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_ROSY, 7, V_GREENMAP, true}, // SKINCOLOR_JADE
|
{"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 10, V_GREENMAP, true}, // SKINCOLOR_JADE
|
||||||
{"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT
|
|
||||||
{"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT
|
{"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT
|
||||||
{"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_MASTER
|
{"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER
|
||||||
{"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD
|
{"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD
|
||||||
{"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
|
|
||||||
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
|
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
|
||||||
{"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND
|
{"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND
|
||||||
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_TAFFY, 10, V_AQUAMAP, true}, // SKINCOLOR_AQUA
|
{"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
|
||||||
|
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA
|
||||||
{"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL
|
{"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL
|
||||||
|
{"Ocean", { 120, 121, 122, 122, 123, 141, 142, 142, 136, 137, 138, 138, 139, 139, 253, 253}, SKINCOLOR_TANGERINE, 4, V_AQUAMAP, true}, // SKINCOLOR_OCEAN
|
||||||
{"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE
|
{"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE
|
||||||
{"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN
|
{"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN
|
||||||
{"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE
|
{"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE
|
||||||
|
@ -21661,12 +21661,12 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||||
{"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM
|
{"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM
|
||||||
{"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY
|
{"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY
|
||||||
{"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK
|
{"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK
|
||||||
{"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE
|
{"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_BLUEMAP, true}, // SKINCOLOR_SAPPHIRE
|
||||||
{"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 6, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC
|
{"Arctic", { 0, 1, 3, 4, 145, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC
|
||||||
{"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER
|
{"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER
|
||||||
{"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE
|
{"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE
|
||||||
{"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT
|
{"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT
|
||||||
{"Midnight", { 171, 171, 172, 173, 173, 174, 155, 156, 157, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT
|
{"Midnight", { 171, 171, 172, 173, 173, 174, 175, 157, 158, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT
|
||||||
{"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY
|
{"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY
|
||||||
{"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR
|
{"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR
|
||||||
{"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK
|
{"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK
|
||||||
|
@ -21676,21 +21676,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||||
{"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE
|
{"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE
|
||||||
{"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA
|
{"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA
|
||||||
{"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 182, 164, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM
|
{"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 182, 164, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM
|
||||||
{"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL
|
{"Siberite", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_SIBERITE
|
||||||
{"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA
|
{"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA
|
||||||
{"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON
|
{"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON
|
||||||
{"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET
|
{"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET
|
||||||
{"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL
|
{"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL
|
||||||
{"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC
|
{"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC
|
||||||
{"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE
|
{"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE
|
||||||
{"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE
|
{"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE
|
||||||
{"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM
|
{"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM
|
||||||
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY
|
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY
|
||||||
{"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_TAFFY
|
{"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY
|
||||||
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_ROSY
|
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY
|
||||||
{"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY
|
{"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY
|
||||||
{"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 12, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA
|
{"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 12, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA
|
||||||
{"Volcanic", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC
|
{"Volcanic", { 54, 36, 42, 44, 45, 46, 46, 47, 28, 253, 253, 254, 254, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC
|
||||||
|
|
||||||
// super
|
// super
|
||||||
{"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1
|
{"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#include "y_inter.h"
|
#include "y_inter.h"
|
||||||
#include "hu_stuff.h" // HU_AddChatText
|
#include "hu_stuff.h" // HU_AddChatText
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_netcmd.h" // IsPlayerAdmin
|
#include "netcode/d_netcmd.h" // IsPlayerAdmin
|
||||||
#include "m_menu.h" // Player Setup menu color stuff
|
#include "m_menu.h" // Player Setup menu color stuff
|
||||||
#include "m_misc.h" // M_MapNumber
|
#include "m_misc.h" // M_MapNumber
|
||||||
#include "b_bot.h" // B_UpdateBotleader
|
#include "b_bot.h" // B_UpdateBotleader
|
||||||
#include "d_clisrv.h" // CL_RemovePlayer
|
#include "netcode/d_clisrv.h" // CL_RemovePlayer
|
||||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
|
@ -3566,7 +3566,7 @@ static int lib_gAddGametype(lua_State *L)
|
||||||
// Partly lifted from Got_AddPlayer
|
// Partly lifted from Got_AddPlayer
|
||||||
static int lib_gAddPlayer(lua_State *L)
|
static int lib_gAddPlayer(lua_State *L)
|
||||||
{
|
{
|
||||||
INT16 i, newplayernum, botcount = 1;
|
INT16 i, newplayernum;
|
||||||
player_t *newplayer;
|
player_t *newplayer;
|
||||||
SINT8 skinnum = 0, bot;
|
SINT8 skinnum = 0, bot;
|
||||||
|
|
||||||
|
@ -3574,10 +3574,8 @@ static int lib_gAddPlayer(lua_State *L)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (players[i].bot)
|
|
||||||
botcount++; // How many of us are there already?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= MAXPLAYERS)
|
if (i >= MAXPLAYERS)
|
||||||
{
|
{
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
@ -3848,7 +3846,7 @@ static int lib_gDoReborn(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another Lua function that doesn't actually exist!
|
// Another Lua function that doesn't actually exist!
|
||||||
// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
|
// Sets nextmapoverride, skipstats and nextgametype without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
|
||||||
static int lib_gSetCustomExitVars(lua_State *L)
|
static int lib_gSetCustomExitVars(lua_State *L)
|
||||||
{
|
{
|
||||||
int n = lua_gettop(L); // Num arguments
|
int n = lua_gettop(L); // Num arguments
|
||||||
|
@ -3857,18 +3855,21 @@ static int lib_gSetCustomExitVars(lua_State *L)
|
||||||
|
|
||||||
// LUA EXTENSION: Custom exit like support
|
// LUA EXTENSION: Custom exit like support
|
||||||
// Supported:
|
// Supported:
|
||||||
// G_SetCustomExitVars(); [reset to defaults]
|
// G_SetCustomExitVars(); [reset to defaults]
|
||||||
// G_SetCustomExitVars(int) [nextmap override only]
|
// G_SetCustomExitVars(int) [nextmap override only]
|
||||||
// G_SetCustomExitVars(nil, int) [skipstats only]
|
// G_SetCustomExitVars(nil, int) [skipstats only]
|
||||||
// G_SetCustomExitVars(int, int) [both of the above]
|
// G_SetCustomExitVars(int, int) [both of the above]
|
||||||
|
// G_SetCustomExitVars(int, int, int) [nextmapoverride, skipstats and nextgametype]
|
||||||
|
|
||||||
nextmapoverride = 0;
|
nextmapoverride = 0;
|
||||||
skipstats = 0;
|
skipstats = 0;
|
||||||
|
nextgametype = -1;
|
||||||
|
|
||||||
if (n >= 1)
|
if (n >= 1)
|
||||||
{
|
{
|
||||||
nextmapoverride = (INT16)luaL_optinteger(L, 1, 0);
|
nextmapoverride = (INT16)luaL_optinteger(L, 1, 0);
|
||||||
skipstats = (INT16)luaL_optinteger(L, 2, 0);
|
skipstats = (INT16)luaL_optinteger(L, 2, 0);
|
||||||
|
nextgametype = (INT16)luaL_optinteger(L, 3, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
#include "netcode/net_command.h"
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
|
@ -615,7 +616,7 @@ static int cvar_get(lua_State *L)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (devparm)
|
if (devparm)
|
||||||
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
|
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
|
||||||
#include "m_perfstats.h"
|
#include "m_perfstats.h"
|
||||||
#include "d_netcmd.h" // for cv_perfstats
|
#include "netcode/d_netcmd.h" // for cv_perfstats
|
||||||
#include "i_system.h" // I_GetPreciseTime
|
#include "i_system.h" // I_GetPreciseTime
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
|
|
|
@ -282,7 +282,6 @@ static int patch_get(lua_State *L)
|
||||||
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
|
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
|
||||||
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
|
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
|
||||||
|
|
||||||
// patches are invalidated when switching renderers
|
|
||||||
if (!patch) {
|
if (!patch) {
|
||||||
if (field == patch_valid) {
|
if (field == patch_valid) {
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
|
@ -436,7 +435,7 @@ static int camera_set(lua_State *L)
|
||||||
cam->momz = luaL_checkfixed(L, 3);
|
cam->momz = luaL_checkfixed(L, 3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS, camera_opt[field]);
|
return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1487,7 +1486,6 @@ void LUA_SetHudHook(int hook, huddrawlist_h list)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HUD_HOOK(intermission):
|
case HUD_HOOK(intermission):
|
||||||
lua_pushboolean(gL, intertype == int_spec &&
|
lua_pushboolean(gL, stagefailed);
|
||||||
stagefailed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -805,8 +805,9 @@ static int sector_set(lua_State *L)
|
||||||
case sector_fslope: // f_slope
|
case sector_fslope: // f_slope
|
||||||
case sector_cslope: // c_slope
|
case sector_cslope: // c_slope
|
||||||
case sector_friction: // friction
|
case sector_friction: // friction
|
||||||
default:
|
|
||||||
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
||||||
|
default:
|
||||||
|
return luaL_error(L, "sector_t has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
case sector_floorheight: { // floorheight
|
case sector_floorheight: { // floorheight
|
||||||
boolean flag;
|
boolean flag;
|
||||||
mobj_t *ptmthing = tmthing;
|
mobj_t *ptmthing = tmthing;
|
||||||
|
@ -1284,8 +1285,9 @@ static int side_set(lua_State *L)
|
||||||
case side_sector:
|
case side_sector:
|
||||||
case side_special:
|
case side_special:
|
||||||
case side_text:
|
case side_text:
|
||||||
default:
|
|
||||||
return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]);
|
return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]);
|
||||||
|
default:
|
||||||
|
return luaL_error(L, "side_t has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
case side_textureoffset:
|
case side_textureoffset:
|
||||||
side->textureoffset = luaL_checkfixed(L, 3);
|
side->textureoffset = luaL_checkfixed(L, 3);
|
||||||
break;
|
break;
|
||||||
|
@ -2296,8 +2298,9 @@ static int ffloor_set(lua_State *L)
|
||||||
case ffloor_target: // target
|
case ffloor_target: // target
|
||||||
case ffloor_next: // next
|
case ffloor_next: // next
|
||||||
case ffloor_prev: // prev
|
case ffloor_prev: // prev
|
||||||
default:
|
|
||||||
return luaL_error(L, "ffloor_t field " LUA_QS " cannot be set.", ffloor_opt[field]);
|
return luaL_error(L, "ffloor_t field " LUA_QS " cannot be set.", ffloor_opt[field]);
|
||||||
|
default:
|
||||||
|
return luaL_error(L, "ffloor_t has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
case ffloor_topheight: { // topheight
|
case ffloor_topheight: { // topheight
|
||||||
boolean flag;
|
boolean flag;
|
||||||
fixed_t lastpos = *ffloor->topheight;
|
fixed_t lastpos = *ffloor->topheight;
|
||||||
|
@ -2431,8 +2434,9 @@ static int slope_set(lua_State *L)
|
||||||
case slope_d: // d
|
case slope_d: // d
|
||||||
case slope_flags: // flags
|
case slope_flags: // flags
|
||||||
case slope_normal: // normal
|
case slope_normal: // normal
|
||||||
default:
|
|
||||||
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
||||||
|
default:
|
||||||
|
return luaL_error(L, "pslope_t has no field named " LUA_QS ".", lua_tostring(L, 2));
|
||||||
case slope_o: { // o
|
case slope_o: { // o
|
||||||
luaL_checktype(L, 3, LUA_TTABLE);
|
luaL_checktype(L, 3, LUA_TTABLE);
|
||||||
|
|
||||||
|
|
|
@ -925,6 +925,8 @@ enum mapthing_e {
|
||||||
mapthing_type,
|
mapthing_type,
|
||||||
mapthing_options,
|
mapthing_options,
|
||||||
mapthing_scale,
|
mapthing_scale,
|
||||||
|
mapthing_spritexscale,
|
||||||
|
mapthing_spriteyscale,
|
||||||
mapthing_z,
|
mapthing_z,
|
||||||
mapthing_extrainfo,
|
mapthing_extrainfo,
|
||||||
mapthing_tag,
|
mapthing_tag,
|
||||||
|
@ -944,6 +946,8 @@ const char *const mapthing_opt[] = {
|
||||||
"type",
|
"type",
|
||||||
"options",
|
"options",
|
||||||
"scale",
|
"scale",
|
||||||
|
"spritexscale",
|
||||||
|
"spriteyscale",
|
||||||
"z",
|
"z",
|
||||||
"extrainfo",
|
"extrainfo",
|
||||||
"tag",
|
"tag",
|
||||||
|
@ -999,7 +1003,13 @@ static int mapthing_get(lua_State *L)
|
||||||
lua_pushinteger(L, mt->options);
|
lua_pushinteger(L, mt->options);
|
||||||
break;
|
break;
|
||||||
case mapthing_scale:
|
case mapthing_scale:
|
||||||
lua_pushinteger(L, mt->scale);
|
lua_pushfixed(L, mt->scale);
|
||||||
|
break;
|
||||||
|
case mapthing_spritexscale:
|
||||||
|
lua_pushfixed(L, mt->spritexscale);
|
||||||
|
break;
|
||||||
|
case mapthing_spriteyscale:
|
||||||
|
lua_pushfixed(L, mt->spriteyscale);
|
||||||
break;
|
break;
|
||||||
case mapthing_z:
|
case mapthing_z:
|
||||||
lua_pushinteger(L, mt->z);
|
lua_pushinteger(L, mt->z);
|
||||||
|
@ -1072,6 +1082,12 @@ static int mapthing_set(lua_State *L)
|
||||||
case mapthing_scale:
|
case mapthing_scale:
|
||||||
mt->scale = luaL_checkfixed(L, 3);
|
mt->scale = luaL_checkfixed(L, 3);
|
||||||
break;
|
break;
|
||||||
|
case mapthing_spritexscale:
|
||||||
|
mt->spritexscale = luaL_checkfixed(L, 3);
|
||||||
|
break;
|
||||||
|
case mapthing_spriteyscale:
|
||||||
|
mt->spriteyscale = luaL_checkfixed(L, 3);
|
||||||
|
break;
|
||||||
case mapthing_z:
|
case mapthing_z:
|
||||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "p_slopes.h" // for P_SlopeById and slopelist
|
#include "p_slopes.h" // for P_SlopeById and slopelist
|
||||||
#include "p_polyobj.h" // polyobj_t, PolyObjects
|
#include "p_polyobj.h" // polyobj_t, PolyObjects
|
||||||
#ifdef LUA_ALLOW_BYTECODE
|
#ifdef LUA_ALLOW_BYTECODE
|
||||||
#include "d_netfil.h" // for LUA_DumpFile
|
#include "netcode/d_netfil.h" // for LUA_DumpFile
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
|
|
|
@ -25,6 +25,7 @@ enum skin {
|
||||||
skin_flags,
|
skin_flags,
|
||||||
skin_realname,
|
skin_realname,
|
||||||
skin_hudname,
|
skin_hudname,
|
||||||
|
skin_supername,
|
||||||
skin_ability,
|
skin_ability,
|
||||||
skin_ability2,
|
skin_ability2,
|
||||||
skin_thokitem,
|
skin_thokitem,
|
||||||
|
@ -63,6 +64,7 @@ static const char *const skin_opt[] = {
|
||||||
"flags",
|
"flags",
|
||||||
"realname",
|
"realname",
|
||||||
"hudname",
|
"hudname",
|
||||||
|
"supername",
|
||||||
"ability",
|
"ability",
|
||||||
"ability2",
|
"ability2",
|
||||||
"thokitem",
|
"thokitem",
|
||||||
|
@ -126,6 +128,9 @@ static int skin_get(lua_State *L)
|
||||||
case skin_hudname:
|
case skin_hudname:
|
||||||
lua_pushstring(L, skin->hudname);
|
lua_pushstring(L, skin->hudname);
|
||||||
break;
|
break;
|
||||||
|
case skin_supername:
|
||||||
|
lua_pushstring(L, skin->supername);
|
||||||
|
break;
|
||||||
case skin_ability:
|
case skin_ability:
|
||||||
lua_pushinteger(L, skin->ability);
|
lua_pushinteger(L, skin->ability);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "r_local.h"
|
#include "r_local.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "d_net.h"
|
#include "netcode/d_net.h"
|
||||||
|
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
|
@ -1102,6 +1102,8 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
||||||
|
|
||||||
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
|
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
|
||||||
mt->scale = player->mo->scale;
|
mt->scale = player->mo->scale;
|
||||||
|
mt->spritexscale = player->mo->spritexscale;
|
||||||
|
mt->spriteyscale = player->mo->spriteyscale;
|
||||||
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
|
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
|
||||||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||||
mt->pitch = mt->roll = 0;
|
mt->pitch = mt->roll = 0;
|
||||||
|
|
51
src/m_cond.c
51
src/m_cond.c
|
@ -467,6 +467,15 @@ UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data)
|
||||||
|
|
||||||
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
|
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
|
||||||
{
|
{
|
||||||
|
if (dedicated)
|
||||||
|
{
|
||||||
|
// If you're in a dedicated server, every level is unlocked.
|
||||||
|
// Yes, technically this means you can view any level by
|
||||||
|
// running a dedicated server and joining it yourself, but
|
||||||
|
// that's better than making dedicated server's lives hell.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
|
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -480,6 +489,48 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
|
||||||
|
{
|
||||||
|
if (M_MapLocked(mapnum, data) == true)
|
||||||
|
{
|
||||||
|
// Warping to locked maps is definitely always a cheat
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((gametypedefaultrules[gt] & GTR_CAMPAIGN) == 0)
|
||||||
|
{
|
||||||
|
// Not a campaign, do whatever you want.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_IsSpecialStage(mapnum))
|
||||||
|
{
|
||||||
|
// Warping to special stages is a cheat
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->menuflags & LF2_HIDEINMENU)
|
||||||
|
{
|
||||||
|
// You're never allowed to warp to this level.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapheaderinfo[mapnum-1]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
{
|
||||||
|
// You're always allowed to warp to this level.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapnum == spstage_start)
|
||||||
|
{
|
||||||
|
// Warping to the first level is never a cheat
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's only a cheat if you've never been there.
|
||||||
|
return (!(data->mapvisited[mapnum-1]));
|
||||||
|
}
|
||||||
|
|
||||||
INT32 M_CountEmblems(gamedata_t *data)
|
INT32 M_CountEmblems(gamedata_t *data)
|
||||||
{
|
{
|
||||||
INT32 found = 0, i;
|
INT32 found = 0, i;
|
||||||
|
|
|
@ -252,6 +252,7 @@ void M_SilentUpdateSkinAvailabilites(void);
|
||||||
UINT8 M_AnySecretUnlocked(gamedata_t *data);
|
UINT8 M_AnySecretUnlocked(gamedata_t *data);
|
||||||
UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data);
|
UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data);
|
||||||
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data);
|
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data);
|
||||||
|
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data);
|
||||||
INT32 M_CountEmblems(gamedata_t *data);
|
INT32 M_CountEmblems(gamedata_t *data);
|
||||||
|
|
||||||
// Emblem shit
|
// Emblem shit
|
||||||
|
|
309
src/m_menu.c
309
src/m_menu.c
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "r_fps.h"
|
#include "r_fps.h"
|
||||||
#include "r_local.h"
|
#include "r_local.h"
|
||||||
|
@ -53,8 +53,10 @@
|
||||||
#include "hardware/hw_main.h"
|
#include "hardware/hw_main.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "d_net.h"
|
#include "netcode/d_net.h"
|
||||||
#include "mserv.h"
|
#include "netcode/mserv.h"
|
||||||
|
#include "netcode/server_connection.h"
|
||||||
|
#include "netcode/client_connection.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "m_anigif.h"
|
#include "m_anigif.h"
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
|
@ -149,9 +151,7 @@ levellist_mode_t levellistmode = LLM_CREATESERVER;
|
||||||
UINT8 maplistoption = 0;
|
UINT8 maplistoption = 0;
|
||||||
|
|
||||||
static char joystickInfo[MAX_JOYSTICKS+1][29];
|
static char joystickInfo[MAX_JOYSTICKS+1][29];
|
||||||
#ifndef NONET
|
|
||||||
static UINT32 serverlistpage;
|
static UINT32 serverlistpage;
|
||||||
#endif
|
|
||||||
|
|
||||||
static UINT8 numsaves = 0;
|
static UINT8 numsaves = 0;
|
||||||
static saveinfo_t* savegameinfo = NULL; // Extra info about the save games.
|
static saveinfo_t* savegameinfo = NULL; // Extra info about the save games.
|
||||||
|
@ -190,10 +190,8 @@ static void M_GoBack(INT32 choice);
|
||||||
static void M_StopMessage(INT32 choice);
|
static void M_StopMessage(INT32 choice);
|
||||||
static boolean stopstopmessage = false;
|
static boolean stopstopmessage = false;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void M_HandleServerPage(INT32 choice);
|
static void M_HandleServerPage(INT32 choice);
|
||||||
static void M_RoomMenu(INT32 choice);
|
static void M_RoomMenu(INT32 choice);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Prototyping is fun, innit?
|
// Prototyping is fun, innit?
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -296,7 +294,6 @@ static void M_SetupMultiPlayer2(INT32 choice);
|
||||||
static void M_StartSplitServerMenu(INT32 choice);
|
static void M_StartSplitServerMenu(INT32 choice);
|
||||||
static void M_StartServer(INT32 choice);
|
static void M_StartServer(INT32 choice);
|
||||||
static void M_ServerOptions(INT32 choice);
|
static void M_ServerOptions(INT32 choice);
|
||||||
#ifndef NONET
|
|
||||||
static void M_StartServerMenu(INT32 choice);
|
static void M_StartServerMenu(INT32 choice);
|
||||||
static void M_ConnectMenu(INT32 choice);
|
static void M_ConnectMenu(INT32 choice);
|
||||||
static void M_ConnectMenuModChecks(INT32 choice);
|
static void M_ConnectMenuModChecks(INT32 choice);
|
||||||
|
@ -304,7 +301,6 @@ static void M_Refresh(INT32 choice);
|
||||||
static void M_Connect(INT32 choice);
|
static void M_Connect(INT32 choice);
|
||||||
static void M_ChooseRoom(INT32 choice);
|
static void M_ChooseRoom(INT32 choice);
|
||||||
menu_t MP_MainDef;
|
menu_t MP_MainDef;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
// Split into multiple parts due to size
|
// Split into multiple parts due to size
|
||||||
|
@ -382,11 +378,9 @@ static void M_DrawVideoMode(void);
|
||||||
static void M_DrawColorMenu(void);
|
static void M_DrawColorMenu(void);
|
||||||
static void M_DrawScreenshotMenu(void);
|
static void M_DrawScreenshotMenu(void);
|
||||||
static void M_DrawMonitorToggles(void);
|
static void M_DrawMonitorToggles(void);
|
||||||
#ifndef NONET
|
|
||||||
static void M_DrawConnectMenu(void);
|
static void M_DrawConnectMenu(void);
|
||||||
static void M_DrawMPMainMenu(void);
|
static void M_DrawMPMainMenu(void);
|
||||||
static void M_DrawRoomMenu(void);
|
static void M_DrawRoomMenu(void);
|
||||||
#endif
|
|
||||||
static void M_DrawJoystick(void);
|
static void M_DrawJoystick(void);
|
||||||
static void M_DrawSetupMultiPlayerMenu(void);
|
static void M_DrawSetupMultiPlayerMenu(void);
|
||||||
static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color);
|
static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color);
|
||||||
|
@ -401,10 +395,8 @@ static void M_HandleImageDef(INT32 choice);
|
||||||
static void M_HandleLoadSave(INT32 choice);
|
static void M_HandleLoadSave(INT32 choice);
|
||||||
static void M_HandleLevelStats(INT32 choice);
|
static void M_HandleLevelStats(INT32 choice);
|
||||||
static void M_HandlePlaystyleMenu(INT32 choice);
|
static void M_HandlePlaystyleMenu(INT32 choice);
|
||||||
#ifndef NONET
|
|
||||||
static boolean M_CancelConnect(void);
|
static boolean M_CancelConnect(void);
|
||||||
static void M_HandleConnectIP(INT32 choice);
|
static void M_HandleConnectIP(INT32 choice);
|
||||||
#endif
|
|
||||||
static void M_HandleSetupMultiPlayer(INT32 choice);
|
static void M_HandleSetupMultiPlayer(INT32 choice);
|
||||||
static void M_HandleVideoMode(INT32 choice);
|
static void M_HandleVideoMode(INT32 choice);
|
||||||
|
|
||||||
|
@ -503,11 +495,7 @@ consvar_t cv_dummyloadless = CVAR_INIT ("dummyloadless", "In-game", CV_HIDEN, lo
|
||||||
static menuitem_t MainMenu[] =
|
static menuitem_t MainMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76},
|
{IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76},
|
||||||
#ifndef NONET
|
|
||||||
{IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84},
|
{IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84},
|
||||||
#else
|
|
||||||
{IT_STRING|IT_CALL, NULL, "Multiplayer", M_StartSplitServerMenu, 84},
|
|
||||||
#endif
|
|
||||||
{IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92},
|
{IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92},
|
||||||
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100},
|
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100},
|
||||||
{IT_STRING|IT_CALL, NULL, "Options", M_Options, 108},
|
{IT_STRING|IT_CALL, NULL, "Options", M_Options, 108},
|
||||||
|
@ -930,16 +918,10 @@ static menuitem_t SP_PlayerMenu[] =
|
||||||
static menuitem_t MP_SplitServerMenu[] =
|
static menuitem_t MP_SplitServerMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100},
|
{IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100},
|
||||||
#ifdef NONET // In order to keep player setup accessible.
|
|
||||||
{IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110},
|
|
||||||
{IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120},
|
|
||||||
#endif
|
|
||||||
{IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130},
|
{IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130},
|
||||||
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140},
|
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140},
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
static menuitem_t MP_MainMenu[] =
|
static menuitem_t MP_MainMenu[] =
|
||||||
{
|
{
|
||||||
{IT_HEADER, NULL, "Join a game", NULL, 0},
|
{IT_HEADER, NULL, "Join a game", NULL, 0},
|
||||||
|
@ -1026,8 +1008,6 @@ menuitem_t MP_RoomMenu[] =
|
||||||
{IT_DISABLED, NULL, "", M_ChooseRoom, 162},
|
{IT_DISABLED, NULL, "", M_ChooseRoom, 162},
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static menuitem_t MP_PlayerSetupMenu[] =
|
static menuitem_t MP_PlayerSetupMenu[] =
|
||||||
{
|
{
|
||||||
{IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name
|
{IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name
|
||||||
|
@ -1586,14 +1566,12 @@ enum
|
||||||
static menuitem_t OP_ServerOptionsMenu[] =
|
static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_HEADER, NULL, "General", NULL, 0},
|
{IT_HEADER, NULL, "General", NULL, 0},
|
||||||
#ifndef NONET
|
|
||||||
{IT_STRING | IT_CVAR | IT_CV_STRING,
|
{IT_STRING | IT_CVAR | IT_CV_STRING,
|
||||||
NULL, "Server name", &cv_servername, 7},
|
NULL, "Server name", &cv_servername, 7},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
|
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
|
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
|
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36},
|
{IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36},
|
||||||
#endif
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41},
|
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46},
|
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46},
|
||||||
|
|
||||||
|
@ -1632,7 +1610,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216},
|
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221},
|
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221},
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
{IT_HEADER, NULL, "Advanced", NULL, 230},
|
{IT_HEADER, NULL, "Advanced", NULL, 230},
|
||||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236},
|
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236},
|
||||||
|
|
||||||
|
@ -1640,7 +1617,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256},
|
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261},
|
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261},
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_MonitorToggleMenu[] =
|
static menuitem_t OP_MonitorToggleMenu[] =
|
||||||
|
@ -1954,11 +1930,7 @@ menu_t MP_SplitServerDef =
|
||||||
MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
|
MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
|
||||||
"M_MULTI",
|
"M_MULTI",
|
||||||
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
|
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
|
||||||
#ifndef NONET
|
|
||||||
&MP_MainDef,
|
&MP_MainDef,
|
||||||
#else
|
|
||||||
&MainDef,
|
|
||||||
#endif
|
|
||||||
MP_SplitServerMenu,
|
MP_SplitServerMenu,
|
||||||
M_DrawServerMenu,
|
M_DrawServerMenu,
|
||||||
27, 30 - 50,
|
27, 30 - 50,
|
||||||
|
@ -1966,8 +1938,6 @@ menu_t MP_SplitServerDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
menu_t MP_MainDef =
|
menu_t MP_MainDef =
|
||||||
{
|
{
|
||||||
MN_MP_MAIN,
|
MN_MP_MAIN,
|
||||||
|
@ -2019,15 +1989,10 @@ menu_t MP_RoomDef =
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
menu_t MP_PlayerSetupDef =
|
menu_t MP_PlayerSetupDef =
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
|
|
||||||
#else
|
|
||||||
MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
|
MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
|
||||||
#endif
|
|
||||||
"M_SPLAYR",
|
"M_SPLAYR",
|
||||||
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
|
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
|
||||||
&MainDef, // doesn't matter
|
&MainDef, // doesn't matter
|
||||||
|
@ -2649,7 +2614,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval,
|
||||||
{
|
{
|
||||||
strncpy(curbgname, defaultname, 9);
|
strncpy(curbgname, defaultname, 9);
|
||||||
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed;
|
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -2787,6 +2752,7 @@ void M_SetMenuCurBackground(const char *defaultname)
|
||||||
{
|
{
|
||||||
char name[9];
|
char name[9];
|
||||||
strncpy(name, defaultname, 8);
|
strncpy(name, defaultname, 8);
|
||||||
|
name[8] = '\0';
|
||||||
M_IterateMenuTree(MIT_SetCurBackground, &name);
|
M_IterateMenuTree(MIT_SetCurBackground, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2843,8 +2809,8 @@ static void M_HandleMenuPresState(menu_t *newMenu)
|
||||||
curfadevalue = 16;
|
curfadevalue = 16;
|
||||||
curhidepics = hidetitlepics;
|
curhidepics = hidetitlepics;
|
||||||
curbgcolor = -1;
|
curbgcolor = -1;
|
||||||
curbgxspeed = titlescrollxspeed;
|
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||||
curbgyspeed = titlescrollyspeed;
|
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
|
||||||
curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus
|
curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus
|
||||||
|
|
||||||
curttmode = ttmode;
|
curttmode = ttmode;
|
||||||
|
@ -3196,7 +3162,7 @@ boolean M_Responder(event_t *ev)
|
||||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
|
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (gamestate == GS_TITLESCREEN && finalecount < TICRATE)
|
if (gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
|
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
|
||||||
|
@ -3956,9 +3922,7 @@ void M_Init(void)
|
||||||
OP_JoystickSetMenu[i].itemaction = M_AssignJoystick;
|
OP_JoystickSetMenu[i].itemaction = M_AssignJoystick;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
CV_RegisterVar(&cv_serversort);
|
CV_RegisterVar(&cv_serversort);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_InitCharacterTables(void)
|
void M_InitCharacterTables(void)
|
||||||
|
@ -11108,7 +11072,6 @@ static void M_EndGame(INT32 choice)
|
||||||
|
|
||||||
#define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT)
|
#define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT)
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static UINT32 localservercount;
|
static UINT32 localservercount;
|
||||||
|
|
||||||
static void M_HandleServerPage(INT32 choice)
|
static void M_HandleServerPage(INT32 choice)
|
||||||
|
@ -11380,11 +11343,9 @@ static int ServerListEntryComparator_modified(const void *entry1, const void *en
|
||||||
// Default to strcmp.
|
// Default to strcmp.
|
||||||
return strcmp(sa->info.servername, sb->info.servername);
|
return strcmp(sa->info.servername, sb->info.servername);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void M_SortServerList(void)
|
void M_SortServerList(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
switch(cv_serversort.value)
|
switch(cv_serversort.value)
|
||||||
{
|
{
|
||||||
case 0: // Ping.
|
case 0: // Ping.
|
||||||
|
@ -11406,10 +11367,8 @@ void M_SortServerList(void)
|
||||||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename);
|
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
#ifdef UPDATE_ALERT
|
#ifdef UPDATE_ALERT
|
||||||
static boolean M_CheckMODVersion(int id)
|
static boolean M_CheckMODVersion(int id)
|
||||||
{
|
{
|
||||||
|
@ -11608,7 +11567,6 @@ static void M_ChooseRoom(INT32 choice)
|
||||||
if (currentMenu == &MP_ConnectDef)
|
if (currentMenu == &MP_ConnectDef)
|
||||||
M_Refresh(0);
|
M_Refresh(0);
|
||||||
}
|
}
|
||||||
#endif //NONET
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Start Server Menu
|
// Start Server Menu
|
||||||
|
@ -11656,7 +11614,6 @@ static void M_DrawServerMenu(void)
|
||||||
{
|
{
|
||||||
M_DrawGenericMenu();
|
M_DrawGenericMenu();
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// Room name
|
// Room name
|
||||||
if (currentMenu == &MP_ServerDef)
|
if (currentMenu == &MP_ServerDef)
|
||||||
{
|
{
|
||||||
|
@ -11668,15 +11625,10 @@ static void M_DrawServerMenu(void)
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
||||||
V_YELLOWMAP, room_list[menuRoomIndex].name);
|
V_YELLOWMAP, room_list[menuRoomIndex].name);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cv_nextmap.value)
|
if (cv_nextmap.value)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey
|
#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey
|
||||||
#else
|
|
||||||
#define imgheight 100
|
|
||||||
#endif
|
|
||||||
patch_t *PictureOfLevel;
|
patch_t *PictureOfLevel;
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
char headerstr[40];
|
char headerstr[40];
|
||||||
|
@ -11728,7 +11680,6 @@ static void M_ServerOptions(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef)
|
if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef)
|
||||||
{
|
{
|
||||||
OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name
|
OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name
|
||||||
|
@ -11749,7 +11700,6 @@ static void M_ServerOptions(INT32 choice)
|
||||||
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
|
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
|
||||||
OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR;
|
OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable fading because of different menu head. */
|
/* Disable fading because of different menu head. */
|
||||||
if (currentMenu == &OP_MainDef)/* from Options menu */
|
if (currentMenu == &OP_MainDef)/* from Options menu */
|
||||||
|
@ -11761,7 +11711,6 @@ static void M_ServerOptions(INT32 choice)
|
||||||
M_SetupNextMenu(&OP_ServerOptionsDef);
|
M_SetupNextMenu(&OP_ServerOptionsDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void M_StartServerMenu(INT32 choice)
|
static void M_StartServerMenu(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
@ -12028,7 +11977,6 @@ static void M_HandleConnectIP(INT32 choice)
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //!NONET
|
|
||||||
|
|
||||||
// ========================
|
// ========================
|
||||||
// MULTIPLAYER PLAYER SETUP
|
// MULTIPLAYER PLAYER SETUP
|
||||||
|
@ -12054,6 +12002,136 @@ static INT32 setupm_fakeskin;
|
||||||
static menucolor_t *setupm_fakecolor;
|
static menucolor_t *setupm_fakecolor;
|
||||||
static boolean colorgrid;
|
static boolean colorgrid;
|
||||||
|
|
||||||
|
#define COLOR_GRID_ROW_SIZE (16)
|
||||||
|
|
||||||
|
static UINT16 M_GetColorGridIndex(UINT16 color)
|
||||||
|
{
|
||||||
|
menucolor_t *look;
|
||||||
|
UINT16 i = 0;
|
||||||
|
|
||||||
|
if (!skincolors[color].accessible)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (look = menucolorhead; ; i++, look = look->next)
|
||||||
|
{
|
||||||
|
while (!skincolors[look->color].accessible) // skip inaccessible colors
|
||||||
|
{
|
||||||
|
if (look == menucolortail)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
look = look->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (look->color == color)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (look == menucolortail)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT32 M_GridIndexToX(UINT16 index)
|
||||||
|
{
|
||||||
|
return (index % COLOR_GRID_ROW_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT32 M_GridIndexToY(UINT16 index)
|
||||||
|
{
|
||||||
|
return (index / COLOR_GRID_ROW_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT16 M_ColorGridLen(void)
|
||||||
|
{
|
||||||
|
menucolor_t *look;
|
||||||
|
UINT16 i = 0;
|
||||||
|
|
||||||
|
for (look = menucolorhead; ; i++)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (look == menucolortail)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
look = look->next;
|
||||||
|
}
|
||||||
|
while (!skincolors[look->color].accessible); // skip inaccessible colors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT16 M_GridPosToGridIndex(INT32 x, INT32 y)
|
||||||
|
{
|
||||||
|
const UINT16 grid_len = M_ColorGridLen();
|
||||||
|
const UINT16 grid_height = ((grid_len - 1) / COLOR_GRID_ROW_SIZE) + 1;
|
||||||
|
const UINT16 last_row_len = COLOR_GRID_ROW_SIZE - ((grid_height * COLOR_GRID_ROW_SIZE) - grid_len);
|
||||||
|
|
||||||
|
UINT16 row_len = COLOR_GRID_ROW_SIZE;
|
||||||
|
UINT16 new_index = 0;
|
||||||
|
|
||||||
|
while (y < 0)
|
||||||
|
{
|
||||||
|
y += grid_height;
|
||||||
|
}
|
||||||
|
y = (y % grid_height);
|
||||||
|
|
||||||
|
if (y >= grid_height-1 && last_row_len > 0)
|
||||||
|
{
|
||||||
|
row_len = last_row_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (x < 0)
|
||||||
|
{
|
||||||
|
x += row_len;
|
||||||
|
}
|
||||||
|
x = (x % row_len);
|
||||||
|
|
||||||
|
new_index = (y * COLOR_GRID_ROW_SIZE) + x;
|
||||||
|
if (new_index >= grid_len)
|
||||||
|
{
|
||||||
|
new_index = grid_len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static menucolor_t *M_GridIndexToMenuColor(UINT16 index)
|
||||||
|
{
|
||||||
|
menucolor_t *look = menucolorhead;
|
||||||
|
UINT16 i = 0;
|
||||||
|
|
||||||
|
for (look = menucolorhead; ; i++, look = look->next)
|
||||||
|
{
|
||||||
|
while (!skincolors[look->color].accessible) // skip inaccessible colors
|
||||||
|
{
|
||||||
|
if (look == menucolortail)
|
||||||
|
{
|
||||||
|
return menucolorhead;
|
||||||
|
}
|
||||||
|
|
||||||
|
look = look->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == index)
|
||||||
|
{
|
||||||
|
return look;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (look == menucolortail)
|
||||||
|
{
|
||||||
|
return menucolorhead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void M_DrawSetupMultiPlayerMenu(void)
|
static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
{
|
{
|
||||||
INT32 x, y, cursory = 0, flags = 0;
|
INT32 x, y, cursory = 0, flags = 0;
|
||||||
|
@ -12172,32 +12250,54 @@ colordraw:
|
||||||
boolean stoprow = false;
|
boolean stoprow = false;
|
||||||
menucolor_t *mc; // Last accessed color
|
menucolor_t *mc; // Last accessed color
|
||||||
|
|
||||||
|
const UINT16 grid_len = M_ColorGridLen();
|
||||||
|
const UINT16 grid_end_y = M_GridIndexToY(grid_len - 1);
|
||||||
|
|
||||||
|
INT32 grid_select = M_GetColorGridIndex(setupm_fakecolor->color);
|
||||||
|
INT32 grid_select_y = M_GridIndexToY(grid_select);
|
||||||
|
|
||||||
x = 132;
|
x = 132;
|
||||||
y = 66;
|
y = 66;
|
||||||
pos = min(max(0, 16*((M_GetColorIndex(setupm_fakecolor->color)-1)/16) - 64), 16*(M_GetColorIndex(menucolortail->color)/16-1) - 128);
|
|
||||||
mc = M_GetColorFromIndex(pos);
|
pos = M_GridPosToGridIndex(0, max(0, min(grid_select_y - 3, grid_end_y - 7)));
|
||||||
|
mc = M_GridIndexToMenuColor(pos);
|
||||||
|
|
||||||
// Draw grid
|
// Draw grid
|
||||||
V_DrawFill(x-2, y-2, 132, 132, 159);
|
V_DrawFill(x-2, y-2, 132, 132, 159);
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < COLOR_GRID_ROW_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (skincolors[mc->color].accessible && !stoprow)
|
if (skincolors[mc->color].accessible)
|
||||||
{
|
{
|
||||||
M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]);
|
M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]);
|
||||||
if (mc->color == setupm_fakecolor->color) // store current color position
|
|
||||||
{
|
if (mc == setupm_fakecolor) // store current color position
|
||||||
cx = x + i*w;
|
{
|
||||||
cy = y + j*16;
|
cx = x + i*w;
|
||||||
}
|
cy = y + j*16;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mc = mc->next;
|
|
||||||
while (!skincolors[mc->color].accessible && !stoprow) // Find accessible color after this one
|
if (stoprow)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find accessible color after this one
|
||||||
|
do
|
||||||
{
|
{
|
||||||
mc = mc->next;
|
mc = mc->next;
|
||||||
if (mc == menucolortail) stoprow = true;
|
if (mc == menucolortail)
|
||||||
}
|
{
|
||||||
|
stoprow = true;
|
||||||
|
}
|
||||||
|
} while (!skincolors[mc->color].accessible && !stoprow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stoprow)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12318,15 +12418,16 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||||
case KEY_DOWNARROW:
|
case KEY_DOWNARROW:
|
||||||
case KEY_UPARROW:
|
case KEY_UPARROW:
|
||||||
{
|
{
|
||||||
UINT8 i;
|
|
||||||
if (itemOn == 2 && colorgrid)
|
if (itemOn == 2 && colorgrid)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 16; i++)
|
UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
|
||||||
{
|
INT32 x = M_GridIndexToX(index);
|
||||||
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
INT32 y = M_GridIndexToY(index);
|
||||||
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
|
|
||||||
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
y += (choice == KEY_UPARROW) ? -1 : 1;
|
||||||
}
|
|
||||||
|
index = M_GridPosToGridIndex(x, y);
|
||||||
|
setupm_fakecolor = M_GridIndexToMenuColor(index);
|
||||||
}
|
}
|
||||||
else if (choice == KEY_UPARROW)
|
else if (choice == KEY_UPARROW)
|
||||||
M_PrevOpt();
|
M_PrevOpt();
|
||||||
|
@ -12353,8 +12454,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||||
}
|
}
|
||||||
else if (itemOn == 2) // player color
|
else if (itemOn == 2) // player color
|
||||||
{
|
{
|
||||||
S_StartSound(NULL,sfx_menu1); // Tails
|
|
||||||
setupm_fakecolor = setupm_fakecolor->prev;
|
setupm_fakecolor = setupm_fakecolor->prev;
|
||||||
|
S_StartSound(NULL,sfx_menu1); // Tails
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -12393,8 +12494,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||||
}
|
}
|
||||||
else if (itemOn == 2) // player color
|
else if (itemOn == 2) // player color
|
||||||
{
|
{
|
||||||
S_StartSound(NULL,sfx_menu1); // Tails
|
|
||||||
setupm_fakecolor = setupm_fakecolor->next;
|
setupm_fakecolor = setupm_fakecolor->next;
|
||||||
|
S_StartSound(NULL,sfx_menu1); // Tails
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -12404,13 +12505,28 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
if (itemOn == 2) // player color
|
if (itemOn == 2) // player color
|
||||||
{
|
{
|
||||||
S_StartSound(NULL,sfx_menu1);
|
if (colorgrid)
|
||||||
for (i = 0; i < (colorgrid ? 64 : 13); i++) // or (282-charw)/(2*indexwidth)
|
|
||||||
{
|
{
|
||||||
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
|
||||||
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
|
INT32 x = M_GridIndexToX(index);
|
||||||
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
INT32 y = M_GridIndexToY(index);
|
||||||
|
|
||||||
|
y += (choice == KEY_UPARROW) ? -4 : 4;
|
||||||
|
|
||||||
|
index = M_GridPosToGridIndex(x, y);
|
||||||
|
setupm_fakecolor = M_GridIndexToMenuColor(index);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < 13; i++) // or (282-charw)/(2*indexwidth)
|
||||||
|
{
|
||||||
|
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
||||||
|
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
|
||||||
|
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_menu1); // Tails
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -12440,7 +12556,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_DEL:
|
case KEY_DEL:
|
||||||
if (itemOn == 0 && (l = strlen(setupm_name))!=0)
|
if (itemOn == 0 && (l = strlen(setupm_name))!=0)
|
||||||
|
@ -12523,11 +12638,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
||||||
else
|
else
|
||||||
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING);
|
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING);
|
||||||
|
|
||||||
// ditto with colour
|
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||||
if (Playing() && G_GametypeHasTeams())
|
|
||||||
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
|
|
||||||
else
|
|
||||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
|
||||||
|
|
||||||
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
||||||
|
|
||||||
|
@ -12542,7 +12653,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
||||||
|
|
||||||
multi_frame = 0;
|
multi_frame = 0;
|
||||||
multi_tics = 4*FRACUNIT;
|
multi_tics = 4*FRACUNIT;
|
||||||
|
|
||||||
strcpy (setupm_name, cv_playername2.string);
|
strcpy (setupm_name, cv_playername2.string);
|
||||||
|
|
||||||
// set for splitscreen secondary player
|
// set for splitscreen secondary player
|
||||||
|
@ -12568,11 +12679,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
||||||
else
|
else
|
||||||
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING);
|
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING);
|
||||||
|
|
||||||
// ditto with colour
|
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||||
if (Playing() && G_GametypeHasTeams())
|
|
||||||
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
|
|
||||||
else
|
|
||||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
|
||||||
|
|
||||||
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "f_finale.h" // for ttmode_enum
|
#include "f_finale.h" // for ttmode_enum
|
||||||
#include "i_threads.h"
|
#include "i_threads.h"
|
||||||
#include "mserv.h"
|
#include "netcode/mserv.h"
|
||||||
#include "r_things.h" // for SKINNAMESIZE
|
#include "r_things.h" // for SKINNAMESIZE
|
||||||
|
|
||||||
// Compatibility with old-style named NiGHTS replay files.
|
// Compatibility with old-style named NiGHTS replay files.
|
||||||
|
@ -74,7 +74,7 @@ typedef enum
|
||||||
MN_MP_SERVER,
|
MN_MP_SERVER,
|
||||||
MN_MP_CONNECT,
|
MN_MP_CONNECT,
|
||||||
MN_MP_ROOM,
|
MN_MP_ROOM,
|
||||||
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
MN_MP_PLAYERSETUP,
|
||||||
MN_MP_SERVER_OPTIONS,
|
MN_MP_SERVER_OPTIONS,
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "m_perfstats.h"
|
#include "m_perfstats.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
15
src/netcode/CMakeLists.txt
Normal file
15
src/netcode/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
target_sources(SRB2SDL2 PRIVATE
|
||||||
|
d_clisrv.c
|
||||||
|
server_connection.c
|
||||||
|
client_connection.c
|
||||||
|
tic_command.c
|
||||||
|
net_command.c
|
||||||
|
gamestate.c
|
||||||
|
commands.c
|
||||||
|
d_net.c
|
||||||
|
d_netcmd.c
|
||||||
|
d_netfil.c
|
||||||
|
http-mserv.c
|
||||||
|
i_tcp.c
|
||||||
|
mserv.c
|
||||||
|
)
|
13
src/netcode/Sourcefile
Normal file
13
src/netcode/Sourcefile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
d_clisrv.c
|
||||||
|
server_connection.c
|
||||||
|
client_connection.c
|
||||||
|
tic_command.c
|
||||||
|
net_command.c
|
||||||
|
gamestate.c
|
||||||
|
commands.c
|
||||||
|
d_net.c
|
||||||
|
d_netcmd.c
|
||||||
|
d_netfil.c
|
||||||
|
http-mserv.c
|
||||||
|
i_tcp.c
|
||||||
|
mserv.c
|
1178
src/netcode/client_connection.c
Normal file
1178
src/netcode/client_connection.c
Normal file
File diff suppressed because it is too large
Load diff
61
src/netcode/client_connection.h
Normal file
61
src/netcode/client_connection.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file client_connection.h
|
||||||
|
/// \brief Client connection handling
|
||||||
|
|
||||||
|
#ifndef __D_CLIENT_CONNECTION__
|
||||||
|
#define __D_CLIENT_CONNECTION__
|
||||||
|
|
||||||
|
#include "../doomtype.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
|
||||||
|
#define MAXSERVERLIST (MAXNETNODES-1)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SINT8 node;
|
||||||
|
serverinfo_pak info;
|
||||||
|
} serverelem_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CL_SEARCHING,
|
||||||
|
CL_CHECKFILES,
|
||||||
|
CL_DOWNLOADFILES,
|
||||||
|
CL_ASKJOIN,
|
||||||
|
CL_LOADFILES,
|
||||||
|
CL_WAITJOINRESPONSE,
|
||||||
|
CL_DOWNLOADSAVEGAME,
|
||||||
|
CL_CONNECTED,
|
||||||
|
CL_ABORTED,
|
||||||
|
CL_ASKFULLFILELIST,
|
||||||
|
CL_CONFIRMCONNECT
|
||||||
|
} cl_mode_t;
|
||||||
|
|
||||||
|
extern serverelem_t serverlist[MAXSERVERLIST];
|
||||||
|
extern UINT32 serverlistcount;
|
||||||
|
|
||||||
|
extern cl_mode_t cl_mode;
|
||||||
|
extern boolean serverisfull; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
|
||||||
|
extern tic_t firstconnectattempttime;
|
||||||
|
extern UINT8 mynode; // my address pointofview server
|
||||||
|
|
||||||
|
void CL_QueryServerList(msg_server_t *list);
|
||||||
|
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||||
|
|
||||||
|
void CL_ConnectToServer(void);
|
||||||
|
boolean CL_SendJoin(void);
|
||||||
|
|
||||||
|
void PT_ServerInfo(SINT8 node);
|
||||||
|
void PT_MoreFilesNeeded(SINT8 node);
|
||||||
|
void PT_ServerRefuse(SINT8 node);
|
||||||
|
void PT_ServerCFG(SINT8 node);
|
||||||
|
|
||||||
|
#endif
|
484
src/netcode/commands.c
Normal file
484
src/netcode/commands.c
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file commands.c
|
||||||
|
/// \brief Various netgame commands, such as kick and ban
|
||||||
|
|
||||||
|
#include "commands.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "client_connection.h"
|
||||||
|
#include "net_command.h"
|
||||||
|
#include "d_netcmd.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "../byteptr.h"
|
||||||
|
#include "../d_main.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../w_wad.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../r_local.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct banreason_s
|
||||||
|
{
|
||||||
|
char *reason;
|
||||||
|
struct banreason_s *prev; //-1
|
||||||
|
struct banreason_s *next; //+1
|
||||||
|
} banreason_t;
|
||||||
|
|
||||||
|
static banreason_t *reasontail = NULL; //last entry, use prev
|
||||||
|
static banreason_t *reasonhead = NULL; //1st entry, use next
|
||||||
|
|
||||||
|
void Ban_Add(const char *reason)
|
||||||
|
{
|
||||||
|
banreason_t *reasonlist = malloc(sizeof(*reasonlist));
|
||||||
|
|
||||||
|
if (!reasonlist)
|
||||||
|
return;
|
||||||
|
if (!reason)
|
||||||
|
reason = "NA";
|
||||||
|
|
||||||
|
reasonlist->next = NULL;
|
||||||
|
reasonlist->reason = Z_StrDup(reason);
|
||||||
|
if ((reasonlist->prev = reasontail) == NULL)
|
||||||
|
reasonhead = reasonlist;
|
||||||
|
else
|
||||||
|
reasontail->next = reasonlist;
|
||||||
|
reasontail = reasonlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Ban_Clear(void)
|
||||||
|
{
|
||||||
|
banreason_t *temp;
|
||||||
|
|
||||||
|
I_ClearBans();
|
||||||
|
|
||||||
|
reasontail = NULL;
|
||||||
|
|
||||||
|
while (reasonhead)
|
||||||
|
{
|
||||||
|
temp = reasonhead->next;
|
||||||
|
Z_Free(reasonhead->reason);
|
||||||
|
free(reasonhead);
|
||||||
|
reasonhead = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ban_Load_File(boolean warning)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
const char *address, *mask;
|
||||||
|
char buffer[MAX_WADPATH];
|
||||||
|
|
||||||
|
if (!I_ClearBans)
|
||||||
|
return;
|
||||||
|
|
||||||
|
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
if (warning)
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Could not open ban.txt for ban list\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ban_Clear();
|
||||||
|
|
||||||
|
for (; fgets(buffer, (int)sizeof(buffer), f);)
|
||||||
|
{
|
||||||
|
address = strtok(buffer, " \t\r\n");
|
||||||
|
mask = strtok(NULL, " \t\r\n");
|
||||||
|
|
||||||
|
I_SetBanAddress(address, mask);
|
||||||
|
|
||||||
|
Ban_Add(strtok(NULL, "\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D_SaveBan(void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
banreason_t *reasonlist = reasonhead;
|
||||||
|
const char *address, *mask;
|
||||||
|
const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt");
|
||||||
|
|
||||||
|
if (!reasonhead)
|
||||||
|
{
|
||||||
|
remove(path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(path, "w");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Could not save ban list into ban.txt\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
|
||||||
|
{
|
||||||
|
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
|
||||||
|
fprintf(f, "%s 0", address);
|
||||||
|
else
|
||||||
|
fprintf(f, "%s %s", address, mask);
|
||||||
|
|
||||||
|
if (reasonlist && reasonlist->reason)
|
||||||
|
fprintf(f, " %s\n", reasonlist->reason);
|
||||||
|
else
|
||||||
|
fprintf(f, " %s\n", "NA");
|
||||||
|
|
||||||
|
if (reasonlist) reasonlist = reasonlist->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_ShowBan(void) //Print out ban list
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const char *address, *mask;
|
||||||
|
banreason_t *reasonlist = reasonhead;
|
||||||
|
|
||||||
|
if (I_GetBanAddress)
|
||||||
|
CONS_Printf(M_GetText("Ban List:\n"));
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
|
||||||
|
{
|
||||||
|
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
|
||||||
|
CONS_Printf("%s: %s ", sizeu1(i+1), address);
|
||||||
|
else
|
||||||
|
CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask);
|
||||||
|
|
||||||
|
if (reasonlist && reasonlist->reason)
|
||||||
|
CONS_Printf("(%s)\n", reasonlist->reason);
|
||||||
|
else
|
||||||
|
CONS_Printf("\n");
|
||||||
|
|
||||||
|
if (reasonlist) reasonlist = reasonlist->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0 && !address)
|
||||||
|
CONS_Printf(M_GetText("(empty)\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_ClearBans(void)
|
||||||
|
{
|
||||||
|
if (!I_ClearBans)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Ban_Clear();
|
||||||
|
D_SaveBan();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_Ban(void)
|
||||||
|
{
|
||||||
|
if (COM_Argc() < 2)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server || IsPlayerAdmin(consoleplayer))
|
||||||
|
{
|
||||||
|
UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
UINT8 *p = buf;
|
||||||
|
const SINT8 pn = nametonum(COM_Argv(1));
|
||||||
|
const INT32 node = playernode[(INT32)pn];
|
||||||
|
|
||||||
|
if (pn == -1 || pn == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WRITEUINT8(p, pn);
|
||||||
|
|
||||||
|
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||||
|
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (server) // only the server is allowed to do this right now
|
||||||
|
{
|
||||||
|
Ban_Add(COM_Argv(2));
|
||||||
|
D_SaveBan(); // save the ban list
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COM_Argc() == 2)
|
||||||
|
{
|
||||||
|
WRITEUINT8(p, KICK_MSG_BANNED);
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t j = COM_Argc();
|
||||||
|
char message[MAX_REASONLENGTH];
|
||||||
|
|
||||||
|
//Steal from the motd code so you don't have to put the reason in quotes.
|
||||||
|
strlcpy(message, COM_Argv(2), sizeof message);
|
||||||
|
for (size_t i = 3; i < j; i++)
|
||||||
|
{
|
||||||
|
strlcat(message, " ", sizeof message);
|
||||||
|
strlcat(message, COM_Argv(i), sizeof message);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITEUINT8(p, KICK_MSG_CUSTOM_BAN);
|
||||||
|
WRITESTRINGN(p, message, MAX_REASONLENGTH);
|
||||||
|
SendNetXCmd(XD_KICK, &buf, p - buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_BanIP(void)
|
||||||
|
{
|
||||||
|
if (COM_Argc() < 2)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server) // Only the server can use this, otherwise does nothing.
|
||||||
|
{
|
||||||
|
const char *address = (COM_Argv(1));
|
||||||
|
const char *reason;
|
||||||
|
|
||||||
|
if (COM_Argc() == 2)
|
||||||
|
reason = NULL;
|
||||||
|
else
|
||||||
|
reason = COM_Argv(2);
|
||||||
|
|
||||||
|
|
||||||
|
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
|
||||||
|
{
|
||||||
|
if (reason)
|
||||||
|
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
|
||||||
|
else
|
||||||
|
CONS_Printf("Banned IP address %s\n", address);
|
||||||
|
|
||||||
|
Ban_Add(reason);
|
||||||
|
D_SaveBan();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_ReloadBan(void) //recheck ban.txt
|
||||||
|
{
|
||||||
|
Ban_Load_File(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_Kick(void)
|
||||||
|
{
|
||||||
|
if (COM_Argc() < 2)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server || IsPlayerAdmin(consoleplayer))
|
||||||
|
{
|
||||||
|
UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
UINT8 *p = buf;
|
||||||
|
const SINT8 pn = nametonum(COM_Argv(1));
|
||||||
|
|
||||||
|
if (pn == -1 || pn == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Special case if we are trying to kick a player who is downloading the game state:
|
||||||
|
// trigger a timeout instead of kicking them, because a kick would only
|
||||||
|
// take effect after they have finished downloading
|
||||||
|
if (server && playernode[pn] != UINT8_MAX && netnodes[playernode[pn]].sendingsavegame)
|
||||||
|
{
|
||||||
|
Net_ConnectionTimeout(playernode[pn]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITESINT8(p, pn);
|
||||||
|
|
||||||
|
if (COM_Argc() == 2)
|
||||||
|
{
|
||||||
|
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t j = COM_Argc();
|
||||||
|
char message[MAX_REASONLENGTH];
|
||||||
|
|
||||||
|
//Steal from the motd code so you don't have to put the reason in quotes.
|
||||||
|
strlcpy(message, COM_Argv(2), sizeof message);
|
||||||
|
for (size_t i = 3; i < j; i++)
|
||||||
|
{
|
||||||
|
strlcat(message, " ", sizeof message);
|
||||||
|
strlcat(message, COM_Argv(i), sizeof message);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITEUINT8(p, KICK_MSG_CUSTOM_KICK);
|
||||||
|
WRITESTRINGN(p, message, MAX_REASONLENGTH);
|
||||||
|
SendNetXCmd(XD_KICK, &buf, p - buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_connect(void)
|
||||||
|
{
|
||||||
|
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText(
|
||||||
|
"Connect <serveraddress> (port): connect to a server\n"
|
||||||
|
"Connect ANY: connect to the first lan server found\n"
|
||||||
|
//"Connect SELF: connect to your own server.\n"
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Playing() || titledemo)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server = false;
|
||||||
|
/*
|
||||||
|
if (!stricmp(COM_Argv(1), "self"))
|
||||||
|
{
|
||||||
|
servernode = 0;
|
||||||
|
server = true;
|
||||||
|
/// \bug should be but...
|
||||||
|
//SV_SpawnServer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// used in menu to connect to a server in the list
|
||||||
|
if (netgame && !stricmp(COM_Argv(1), "node"))
|
||||||
|
{
|
||||||
|
servernode = (SINT8)atoi(COM_Argv(2));
|
||||||
|
}
|
||||||
|
else if (netgame)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (I_NetOpenSocket)
|
||||||
|
{
|
||||||
|
I_NetOpenSocket();
|
||||||
|
netgame = true;
|
||||||
|
multiplayer = true;
|
||||||
|
|
||||||
|
if (!stricmp(COM_Argv(1), "any"))
|
||||||
|
servernode = BROADCASTADDR;
|
||||||
|
else if (I_NetMakeNodewPort)
|
||||||
|
{
|
||||||
|
if (COM_Argc() >= 3) // address AND port
|
||||||
|
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
|
||||||
|
else // address only, or address:port
|
||||||
|
servernode = I_NetMakeNode(COM_Argv(1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
|
||||||
|
D_CloseConnection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
splitscreen = false;
|
||||||
|
SplitScreen_OnChange();
|
||||||
|
botingame = false;
|
||||||
|
botskin = 0;
|
||||||
|
CL_ConnectToServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_GetPlayerNum(void)
|
||||||
|
{
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playeringame[i])
|
||||||
|
{
|
||||||
|
if (serverplayer == i)
|
||||||
|
CONS_Printf(M_GetText("num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
|
||||||
|
else
|
||||||
|
CONS_Printf(M_GetText("\x82num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lists all players and their player numbers.
|
||||||
|
*
|
||||||
|
* \sa Command_GetPlayerNum
|
||||||
|
*/
|
||||||
|
void Command_Nodes(void)
|
||||||
|
{
|
||||||
|
size_t maxlen = 0;
|
||||||
|
const char *address;
|
||||||
|
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
const size_t plen = strlen(player_names[i]);
|
||||||
|
if (playeringame[i] && plen > maxlen)
|
||||||
|
maxlen = plen;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i])
|
||||||
|
{
|
||||||
|
CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]);
|
||||||
|
|
||||||
|
if (playernode[i] != UINT8_MAX)
|
||||||
|
{
|
||||||
|
CONS_Printf(" - node %.2d", playernode[i]);
|
||||||
|
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
|
||||||
|
CONS_Printf(" - %s", address);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPlayerAdmin(i))
|
||||||
|
CONS_Printf(M_GetText(" (verified admin)"));
|
||||||
|
|
||||||
|
if (players[i].spectator)
|
||||||
|
CONS_Printf(M_GetText(" (spectator)"));
|
||||||
|
|
||||||
|
CONS_Printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/netcode/commands.h
Normal file
33
src/netcode/commands.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file commands.h
|
||||||
|
/// \brief Various netgame commands, such as kick and ban
|
||||||
|
|
||||||
|
#ifndef __COMMANDS__
|
||||||
|
#define __COMMANDS__
|
||||||
|
|
||||||
|
#include "../doomdef.h"
|
||||||
|
|
||||||
|
#define MAX_REASONLENGTH 30
|
||||||
|
|
||||||
|
void Ban_Add(const char *reason);
|
||||||
|
void D_SaveBan(void);
|
||||||
|
void Ban_Load_File(boolean warning);
|
||||||
|
void Command_ShowBan(void);
|
||||||
|
void Command_ClearBans(void);
|
||||||
|
void Command_Ban(void);
|
||||||
|
void Command_BanIP(void);
|
||||||
|
void Command_ReloadBan(void);
|
||||||
|
void Command_Kick(void);
|
||||||
|
void Command_connect(void);
|
||||||
|
void Command_GetPlayerNum(void);
|
||||||
|
void Command_Nodes(void);
|
||||||
|
|
||||||
|
#endif
|
1736
src/netcode/d_clisrv.c
Normal file
1736
src/netcode/d_clisrv.c
Normal file
File diff suppressed because it is too large
Load diff
135
src/netcode/d_clisrv.h
Normal file
135
src/netcode/d_clisrv.h
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file d_clisrv.h
|
||||||
|
/// \brief high level networking stuff
|
||||||
|
|
||||||
|
#ifndef __D_CLISRV__
|
||||||
|
#define __D_CLISRV__
|
||||||
|
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "../d_ticcmd.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "d_netcmd.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "../tables.h"
|
||||||
|
#include "../d_player.h"
|
||||||
|
#include "mserv.h"
|
||||||
|
|
||||||
|
#define CLIENTBACKUPTICS 32
|
||||||
|
|
||||||
|
#ifdef PACKETDROP
|
||||||
|
void Command_Drop(void);
|
||||||
|
void Command_Droprate(void);
|
||||||
|
#endif
|
||||||
|
#ifdef _DEBUG
|
||||||
|
void Command_Numnodes(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern INT32 mapchangepending;
|
||||||
|
|
||||||
|
// Points inside doomcom
|
||||||
|
extern doomdata_t *netbuffer;
|
||||||
|
|
||||||
|
#define BASEPACKETSIZE offsetof(doomdata_t, u)
|
||||||
|
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
KR_KICK = 1, //Kicked by server
|
||||||
|
KR_PINGLIMIT = 2, //Broke Ping Limit
|
||||||
|
KR_SYNCH = 3, //Synch Failure
|
||||||
|
KR_TIMEOUT = 4, //Connection Timeout
|
||||||
|
KR_BAN = 5, //Banned by server
|
||||||
|
KR_LEAVE = 6, //Quit the game
|
||||||
|
|
||||||
|
} kickreason_t;
|
||||||
|
|
||||||
|
/* the max number of name changes in some time period */
|
||||||
|
#define MAXNAMECHANGES (5)
|
||||||
|
#define NAMECHANGERATE (60*TICRATE)
|
||||||
|
|
||||||
|
extern boolean server;
|
||||||
|
extern boolean serverrunning;
|
||||||
|
#define client (!server)
|
||||||
|
extern boolean dedicated; // For dedicated server
|
||||||
|
extern UINT16 software_MAXPACKETLENGTH;
|
||||||
|
extern boolean acceptnewnode;
|
||||||
|
extern SINT8 servernode;
|
||||||
|
extern tic_t maketic;
|
||||||
|
extern tic_t neededtic;
|
||||||
|
extern INT16 consistancy[BACKUPTICS];
|
||||||
|
|
||||||
|
void Command_Ping_f(void);
|
||||||
|
extern tic_t connectiontimeout;
|
||||||
|
extern UINT16 pingmeasurecount;
|
||||||
|
extern UINT32 realpingtable[MAXPLAYERS];
|
||||||
|
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||||
|
extern tic_t servermaxping;
|
||||||
|
|
||||||
|
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_dedicatedidletime;
|
||||||
|
|
||||||
|
// Used in d_net, the only dependence
|
||||||
|
void D_ClientServerInit(void);
|
||||||
|
|
||||||
|
// Create any new ticcmds and broadcast to other players.
|
||||||
|
void NetUpdate(void);
|
||||||
|
|
||||||
|
// Maintain connections to nodes without timing them all out.
|
||||||
|
void NetKeepAlive(void);
|
||||||
|
|
||||||
|
void GetPackets(void);
|
||||||
|
void ResetNode(INT32 node);
|
||||||
|
INT16 Consistancy(void);
|
||||||
|
|
||||||
|
void SV_StartSinglePlayerServer(void);
|
||||||
|
void SV_SpawnServer(void);
|
||||||
|
void SV_StopServer(void);
|
||||||
|
void SV_ResetServer(void);
|
||||||
|
void CL_AddSplitscreenPlayer(void);
|
||||||
|
void CL_RemoveSplitscreenPlayer(void);
|
||||||
|
void CL_Reset(void);
|
||||||
|
void CL_ClearPlayer(INT32 playernum);
|
||||||
|
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||||
|
void CL_HandleTimeout(void);
|
||||||
|
// Is there a game running
|
||||||
|
boolean Playing(void);
|
||||||
|
|
||||||
|
// Broadcasts special packets to other players
|
||||||
|
// to notify of game exit
|
||||||
|
void D_QuitNetGame(void);
|
||||||
|
|
||||||
|
//? How many ticks to run?
|
||||||
|
boolean TryRunTics(tic_t realtic);
|
||||||
|
|
||||||
|
// extra data for lmps
|
||||||
|
// these functions scare me. they contain magic.
|
||||||
|
/*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum);
|
||||||
|
void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/
|
||||||
|
|
||||||
|
// translate a playername in a player number return -1 if not found and
|
||||||
|
// print a error message in the console
|
||||||
|
SINT8 nametonum(const char *name);
|
||||||
|
|
||||||
|
extern char motd[254], server_context[8];
|
||||||
|
extern UINT8 playernode[MAXPLAYERS];
|
||||||
|
|
||||||
|
INT32 D_NumPlayers(void);
|
||||||
|
INT32 D_NumBots(void);
|
||||||
|
|
||||||
|
tic_t GetLag(INT32 node);
|
||||||
|
|
||||||
|
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||||
|
|
||||||
|
extern UINT8 adminpassmd5[16];
|
||||||
|
extern boolean adminpasswordset;
|
||||||
|
|
||||||
|
extern boolean hu_stopped;
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,19 +16,21 @@
|
||||||
/// This protocol uses a mix of "goback n" and "selective repeat" implementation
|
/// This protocol uses a mix of "goback n" and "selective repeat" implementation
|
||||||
/// The NOTHING packet is sent when connection is idle to acknowledge packets
|
/// The NOTHING packet is sent when connection is idle to acknowledge packets
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "g_game.h"
|
#include "../g_game.h"
|
||||||
#include "i_time.h"
|
#include "../i_time.h"
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
#include "i_system.h"
|
#include "../i_system.h"
|
||||||
#include "m_argv.h"
|
#include "../m_argv.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "w_wad.h"
|
#include "../w_wad.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
#include "z_zone.h"
|
#include "tic_command.h"
|
||||||
|
#include "net_command.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
#include "i_tcp.h"
|
#include "i_tcp.h"
|
||||||
#include "d_main.h" // srb2home
|
#include "../d_main.h" // srb2home
|
||||||
|
|
||||||
//
|
//
|
||||||
// NETWORKING
|
// NETWORKING
|
||||||
|
@ -138,7 +140,6 @@ boolean Net_GetNetStat(void)
|
||||||
#define URGENTFREESLOTNUM 10
|
#define URGENTFREESLOTNUM 10
|
||||||
#define ACKTOSENDTIMEOUT (TICRATE/11)
|
#define ACKTOSENDTIMEOUT (TICRATE/11)
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 acknum;
|
UINT8 acknum;
|
||||||
|
@ -152,7 +153,6 @@ typedef struct
|
||||||
doomdata_t data;
|
doomdata_t data;
|
||||||
} pak;
|
} pak;
|
||||||
} ackpak_t;
|
} ackpak_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -160,10 +160,8 @@ typedef enum
|
||||||
NF_TIMEOUT = 2, // Flag is set when the node got a timeout
|
NF_TIMEOUT = 2, // Flag is set when the node got a timeout
|
||||||
} node_flags_t;
|
} node_flags_t;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// Table of packets that were not acknowleged can be resent (the sender window)
|
// Table of packets that were not acknowleged can be resent (the sender window)
|
||||||
static ackpak_t ackpak[MAXACKPACKETS];
|
static ackpak_t ackpak[MAXACKPACKETS];
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -191,7 +189,6 @@ typedef struct
|
||||||
static node_t nodes[MAXNETNODES];
|
static node_t nodes[MAXNETNODES];
|
||||||
#define NODETIMEOUT 14
|
#define NODETIMEOUT 14
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// return <0 if a < b (mod 256)
|
// return <0 if a < b (mod 256)
|
||||||
// 0 if a = n (mod 256)
|
// 0 if a = n (mod 256)
|
||||||
// >0 if a > b (mod 256)
|
// >0 if a > b (mod 256)
|
||||||
|
@ -214,7 +211,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
|
||||||
static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
||||||
{
|
{
|
||||||
node_t *node = &nodes[doomcom->remotenode];
|
node_t *node = &nodes[doomcom->remotenode];
|
||||||
INT32 i, numfreeslot = 0;
|
INT32 numfreeslot = 0;
|
||||||
|
|
||||||
if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
|
if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
|
||||||
{
|
{
|
||||||
|
@ -222,7 +219,7 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
if (!ackpak[i].acknum)
|
if (!ackpak[i].acknum)
|
||||||
{
|
{
|
||||||
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
||||||
|
@ -279,10 +276,10 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
||||||
*/
|
*/
|
||||||
INT32 Net_GetFreeAcks(boolean urgent)
|
INT32 Net_GetFreeAcks(boolean urgent)
|
||||||
{
|
{
|
||||||
INT32 i, numfreeslot = 0;
|
INT32 numfreeslot = 0;
|
||||||
INT32 n = 0; // Number of free acks found
|
INT32 n = 0; // Number of free acks found
|
||||||
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
if (!ackpak[i].acknum)
|
if (!ackpak[i].acknum)
|
||||||
{
|
{
|
||||||
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
||||||
|
@ -318,7 +315,6 @@ static void RemoveAck(INT32 i)
|
||||||
// We have got a packet, proceed the ack request and ack return
|
// We have got a packet, proceed the ack request and ack return
|
||||||
static boolean Processackpak(void)
|
static boolean Processackpak(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
boolean goodpacket = true;
|
boolean goodpacket = true;
|
||||||
node_t *node = &nodes[doomcom->remotenode];
|
node_t *node = &nodes[doomcom->remotenode];
|
||||||
|
|
||||||
|
@ -327,7 +323,7 @@ static boolean Processackpak(void)
|
||||||
{
|
{
|
||||||
node->remotefirstack = netbuffer->ackreturn;
|
node->remotefirstack = netbuffer->ackreturn;
|
||||||
// Search the ackbuffer and free it
|
// Search the ackbuffer and free it
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
|
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
|
||||||
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
|
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
|
||||||
{
|
{
|
||||||
|
@ -349,7 +345,7 @@ static boolean Processackpak(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if it is not already in the queue
|
// Check if it is not already in the queue
|
||||||
for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
|
for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
|
||||||
if (node->acktosend[i] == ack)
|
if (node->acktosend[i] == ack)
|
||||||
{
|
{
|
||||||
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
|
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
|
||||||
|
@ -377,7 +373,7 @@ static boolean Processackpak(void)
|
||||||
while (change)
|
while (change)
|
||||||
{
|
{
|
||||||
change = false;
|
change = false;
|
||||||
for (i = node->acktosend_tail; i != node->acktosend_head;
|
for (INT32 i = node->acktosend_tail; i != node->acktosend_head;
|
||||||
i = (i+1) % MAXACKTOSEND)
|
i = (i+1) % MAXACKTOSEND)
|
||||||
{
|
{
|
||||||
if (cmpack(node->acktosend[i], nextfirstack) <= 0)
|
if (cmpack(node->acktosend[i], nextfirstack) <= 0)
|
||||||
|
@ -426,28 +422,20 @@ static boolean Processackpak(void)
|
||||||
}
|
}
|
||||||
return goodpacket;
|
return goodpacket;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// send special packet with only ack on it
|
// send special packet with only ack on it
|
||||||
void Net_SendAcks(INT32 node)
|
void Net_SendAcks(INT32 node)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)node;
|
|
||||||
#else
|
|
||||||
netbuffer->packettype = PT_NOTHING;
|
netbuffer->packettype = PT_NOTHING;
|
||||||
M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
|
M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
|
||||||
HSendPacket(node, false, 0, MAXACKTOSEND);
|
HSendPacket(node, false, 0, MAXACKTOSEND);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void GotAcks(void)
|
static void GotAcks(void)
|
||||||
{
|
{
|
||||||
INT32 i, j;
|
for (INT32 j = 0; j < MAXACKTOSEND; j++)
|
||||||
|
|
||||||
for (j = 0; j < MAXACKTOSEND; j++)
|
|
||||||
if (netbuffer->u.textcmd[j])
|
if (netbuffer->u.textcmd[j])
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode)
|
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode)
|
||||||
{
|
{
|
||||||
if (ackpak[i].acknum == netbuffer->u.textcmd[j])
|
if (ackpak[i].acknum == netbuffer->u.textcmd[j])
|
||||||
|
@ -463,7 +451,6 @@ static void GotAcks(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void Net_ConnectionTimeout(INT32 node)
|
void Net_ConnectionTimeout(INT32 node)
|
||||||
{
|
{
|
||||||
|
@ -472,14 +459,10 @@ void Net_ConnectionTimeout(INT32 node)
|
||||||
return;
|
return;
|
||||||
nodes[node].flags |= NF_TIMEOUT;
|
nodes[node].flags |= NF_TIMEOUT;
|
||||||
|
|
||||||
// Send a very special packet to self (hack the reboundstore queue)
|
if (server)
|
||||||
// Main code will handle it
|
SendKicksForNode(node, KICK_MSG_TIMEOUT | KICK_MSG_KEEP_BODY);
|
||||||
reboundstore[rebound_head].packettype = PT_NODETIMEOUT;
|
else
|
||||||
reboundstore[rebound_head].ack = 0;
|
CL_HandleTimeout();
|
||||||
reboundstore[rebound_head].ackreturn = 0;
|
|
||||||
reboundstore[rebound_head].u.textcmd[0] = (UINT8)node;
|
|
||||||
reboundsize[rebound_head] = (INT16)(BASEPACKETSIZE + 1);
|
|
||||||
rebound_head = (rebound_head+1) % MAXREBOUND;
|
|
||||||
|
|
||||||
// Do not redo it quickly (if we do not close connection it is
|
// Do not redo it quickly (if we do not close connection it is
|
||||||
// for a good reason!)
|
// for a good reason!)
|
||||||
|
@ -489,10 +472,8 @@ void Net_ConnectionTimeout(INT32 node)
|
||||||
// Resend the data if needed
|
// Resend the data if needed
|
||||||
void Net_AckTicker(void)
|
void Net_AckTicker(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
{
|
{
|
||||||
const INT32 nodei = ackpak[i].destinationnode;
|
const INT32 nodei = ackpak[i].destinationnode;
|
||||||
node_t *node = &nodes[nodei];
|
node_t *node = &nodes[nodei];
|
||||||
|
@ -519,7 +500,7 @@ void Net_AckTicker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||||
{
|
{
|
||||||
// This is something like node open flag
|
// This is something like node open flag
|
||||||
if (nodes[i].firstacktosend)
|
if (nodes[i].firstacktosend)
|
||||||
|
@ -536,16 +517,12 @@ void Net_AckTicker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove last packet received ack before resending the ackreturn
|
// Remove last packet received ack before resending the ackreturn
|
||||||
// (the higher layer doesn't have room, or something else ....)
|
// (the higher layer doesn't have room, or something else ....)
|
||||||
void Net_UnAcknowledgePacket(INT32 node)
|
void Net_UnAcknowledgePacket(INT32 node)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)node;
|
|
||||||
#else
|
|
||||||
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
|
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
|
||||||
DEBFILE(va("UnAcknowledge node %d\n", node));
|
DEBFILE(va("UnAcknowledge node %d\n", node));
|
||||||
if (!node)
|
if (!node)
|
||||||
|
@ -577,10 +554,8 @@ void Net_UnAcknowledgePacket(INT32 node)
|
||||||
if (!nodes[node].firstacktosend)
|
if (!nodes[node].firstacktosend)
|
||||||
nodes[node].firstacktosend = 1;
|
nodes[node].firstacktosend = 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
/** Checks if all acks have been received
|
/** Checks if all acks have been received
|
||||||
*
|
*
|
||||||
* \return True if all acks have been received
|
* \return True if all acks have been received
|
||||||
|
@ -588,15 +563,12 @@ void Net_UnAcknowledgePacket(INT32 node)
|
||||||
*/
|
*/
|
||||||
static boolean Net_AllAcksReceived(void)
|
static boolean Net_AllAcksReceived(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
|
||||||
if (ackpak[i].acknum)
|
if (ackpak[i].acknum)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Waits for all ackreturns
|
/** Waits for all ackreturns
|
||||||
*
|
*
|
||||||
|
@ -605,9 +577,6 @@ static boolean Net_AllAcksReceived(void)
|
||||||
*/
|
*/
|
||||||
void Net_WaitAllAckReceived(UINT32 timeout)
|
void Net_WaitAllAckReceived(UINT32 timeout)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)timeout;
|
|
||||||
#else
|
|
||||||
tic_t tictac = I_GetTime();
|
tic_t tictac = I_GetTime();
|
||||||
timeout = tictac + timeout*NEWTICRATE;
|
timeout = tictac + timeout*NEWTICRATE;
|
||||||
|
|
||||||
|
@ -623,7 +592,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
|
||||||
HGetPacket();
|
HGetPacket();
|
||||||
Net_AckTicker();
|
Net_AckTicker();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InitNode(node_t *node)
|
static void InitNode(node_t *node)
|
||||||
|
@ -637,14 +605,10 @@ static void InitNode(node_t *node)
|
||||||
|
|
||||||
static void InitAck(void)
|
static void InitAck(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
|
||||||
ackpak[i].acknum = 0;
|
ackpak[i].acknum = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
InitNode(&nodes[i]);
|
InitNode(&nodes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,17 +619,12 @@ static void InitAck(void)
|
||||||
*/
|
*/
|
||||||
void Net_AbortPacketType(UINT8 packettype)
|
void Net_AbortPacketType(UINT8 packettype)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
(void)packettype;
|
|
||||||
#else
|
|
||||||
INT32 i;
|
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
|
||||||
if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
|
if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
|
||||||
|| packettype == UINT8_MAX))
|
|| packettype == UINT8_MAX))
|
||||||
{
|
{
|
||||||
ackpak[i].acknum = 0;
|
ackpak[i].acknum = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
@ -675,10 +634,6 @@ void Net_AbortPacketType(UINT8 packettype)
|
||||||
// remove a node, clear all ack from this node and reset askret
|
// remove a node, clear all ack from this node and reset askret
|
||||||
void Net_CloseConnection(INT32 node)
|
void Net_CloseConnection(INT32 node)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)node;
|
|
||||||
#else
|
|
||||||
INT32 i;
|
|
||||||
boolean forceclose = (node & FORCECLOSE) != 0;
|
boolean forceclose = (node & FORCECLOSE) != 0;
|
||||||
|
|
||||||
if (node == -1)
|
if (node == -1)
|
||||||
|
@ -708,7 +663,7 @@ void Net_CloseConnection(INT32 node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we are waiting for an ack from this node
|
// check if we are waiting for an ack from this node
|
||||||
for (i = 0; i < MAXACKPACKETS; i++)
|
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||||
if (ackpak[i].acknum && ackpak[i].destinationnode == node)
|
if (ackpak[i].acknum && ackpak[i].destinationnode == node)
|
||||||
{
|
{
|
||||||
if (!forceclose)
|
if (!forceclose)
|
||||||
|
@ -722,10 +677,8 @@ void Net_CloseConnection(INT32 node)
|
||||||
if (server)
|
if (server)
|
||||||
SV_AbortLuaFileTransfer(node);
|
SV_AbortLuaFileTransfer(node);
|
||||||
I_NetFreeNodenum(node);
|
I_NetFreeNodenum(node);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
//
|
//
|
||||||
// Checksum
|
// Checksum
|
||||||
//
|
//
|
||||||
|
@ -734,23 +687,20 @@ static UINT32 NetbufferChecksum(void)
|
||||||
UINT32 c = 0x1234567;
|
UINT32 c = 0x1234567;
|
||||||
const INT32 l = doomcom->datalength - 4;
|
const INT32 l = doomcom->datalength - 4;
|
||||||
const UINT8 *buf = (UINT8 *)netbuffer + 4;
|
const UINT8 *buf = (UINT8 *)netbuffer + 4;
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < l; i++, buf++)
|
for (INT32 i = 0; i < l; i++, buf++)
|
||||||
c += (*buf) * (i+1);
|
c += (*buf) * (i+1);
|
||||||
|
|
||||||
return LONG(c);
|
return LONG(c);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUGFILE
|
#ifdef DEBUGFILE
|
||||||
|
|
||||||
static void fprintfstring(char *s, size_t len)
|
static void fprintfstring(char *s, size_t len)
|
||||||
{
|
{
|
||||||
INT32 mode = 0;
|
INT32 mode = 0;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (size_t i = 0; i < len; i++)
|
||||||
if (s[i] < 32)
|
if (s[i] < 32)
|
||||||
{
|
{
|
||||||
if (!mode)
|
if (!mode)
|
||||||
|
@ -810,6 +760,8 @@ static const char *packettypename[NUMPACKETTYPE] =
|
||||||
"ASKLUAFILE",
|
"ASKLUAFILE",
|
||||||
"HASLUAFILE",
|
"HASLUAFILE",
|
||||||
|
|
||||||
|
"PT_BASICKEEPALIVE",
|
||||||
|
|
||||||
"FILEFRAGMENT",
|
"FILEFRAGMENT",
|
||||||
"FILEACK",
|
"FILEACK",
|
||||||
"FILERECEIVED",
|
"FILERECEIVED",
|
||||||
|
@ -817,7 +769,6 @@ static const char *packettypename[NUMPACKETTYPE] =
|
||||||
"TEXTCMD",
|
"TEXTCMD",
|
||||||
"TEXTCMD2",
|
"TEXTCMD2",
|
||||||
"CLIENTJOIN",
|
"CLIENTJOIN",
|
||||||
"NODETIMEOUT",
|
|
||||||
"LOGIN",
|
"LOGIN",
|
||||||
"TELLFILESNEEDED",
|
"TELLFILESNEEDED",
|
||||||
"MOREFILESNEEDED",
|
"MOREFILESNEEDED",
|
||||||
|
@ -921,7 +872,6 @@ void Command_Drop(void)
|
||||||
{
|
{
|
||||||
INT32 packetquantity;
|
INT32 packetquantity;
|
||||||
const char *packetname;
|
const char *packetname;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (COM_Argc() < 2)
|
if (COM_Argc() < 2)
|
||||||
{
|
{
|
||||||
|
@ -951,11 +901,11 @@ void Command_Drop(void)
|
||||||
packetname = COM_Argv(1);
|
packetname = COM_Argv(1);
|
||||||
|
|
||||||
if (!(stricmp(packetname, "all") && stricmp(packetname, "any")))
|
if (!(stricmp(packetname, "all") && stricmp(packetname, "any")))
|
||||||
for (i = 0; i < NUMPACKETTYPE; i++)
|
for (size_t i = 0; i < NUMPACKETTYPE; i++)
|
||||||
packetdropquantity[i] = packetquantity;
|
packetdropquantity[i] = packetquantity;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < NUMPACKETTYPE; i++)
|
for (size_t i = 0; i < NUMPACKETTYPE; i++)
|
||||||
if (!stricmp(packetname, packettypename[i]))
|
if (!stricmp(packetname, packettypename[i]))
|
||||||
{
|
{
|
||||||
packetdropquantity[i] = packetquantity;
|
packetdropquantity[i] = packetquantity;
|
||||||
|
@ -986,14 +936,12 @@ void Command_Droprate(void)
|
||||||
packetdroprate = droprate;
|
packetdroprate = droprate;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static boolean ShouldDropPacket(void)
|
static boolean ShouldDropPacket(void)
|
||||||
{
|
{
|
||||||
return (packetdropquantity[netbuffer->packettype])
|
return (packetdropquantity[netbuffer->packettype])
|
||||||
|| (packetdroprate != 0 && rand() < (RAND_MAX * (packetdroprate / 100.f))) || packetdroprate == 100;
|
|| (packetdroprate != 0 && rand() < (RAND_MAX * (packetdroprate / 100.f))) || packetdroprate == 100;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// HSendPacket
|
// HSendPacket
|
||||||
|
@ -1028,11 +976,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
||||||
if (!netgame)
|
if (!netgame)
|
||||||
I_Error("Tried to transmit to another node");
|
I_Error("Tried to transmit to another node");
|
||||||
|
|
||||||
#ifdef NONET
|
|
||||||
(void)node;
|
|
||||||
(void)reliable;
|
|
||||||
(void)acknum;
|
|
||||||
#else
|
|
||||||
// do this before GetFreeAcknum because this function backups
|
// do this before GetFreeAcknum because this function backups
|
||||||
// the current packet
|
// the current packet
|
||||||
doomcom->remotenode = (INT16)node;
|
doomcom->remotenode = (INT16)node;
|
||||||
|
@ -1093,8 +1036,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // ndef NONET
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,10 +1053,7 @@ boolean HGetPacket(void)
|
||||||
{
|
{
|
||||||
M_Memcpy(netbuffer, &reboundstore[rebound_tail], reboundsize[rebound_tail]);
|
M_Memcpy(netbuffer, &reboundstore[rebound_tail], reboundsize[rebound_tail]);
|
||||||
doomcom->datalength = reboundsize[rebound_tail];
|
doomcom->datalength = reboundsize[rebound_tail];
|
||||||
if (netbuffer->packettype == PT_NODETIMEOUT)
|
doomcom->remotenode = 0;
|
||||||
doomcom->remotenode = netbuffer->u.textcmd[0];
|
|
||||||
else
|
|
||||||
doomcom->remotenode = 0;
|
|
||||||
|
|
||||||
rebound_tail = (rebound_tail+1) % MAXREBOUND;
|
rebound_tail = (rebound_tail+1) % MAXREBOUND;
|
||||||
#ifdef DEBUGFILE
|
#ifdef DEBUGFILE
|
||||||
|
@ -1128,8 +1066,6 @@ boolean HGetPacket(void)
|
||||||
if (!netgame)
|
if (!netgame)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
//nodejustjoined = I_NetGet();
|
//nodejustjoined = I_NetGet();
|
||||||
|
@ -1189,7 +1125,6 @@ boolean HGetPacket(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif // ndef NONET
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1399,13 +1334,12 @@ void Command_Ping_f(void)
|
||||||
int name_width = 0;
|
int name_width = 0;
|
||||||
int ms_width = 0;
|
int ms_width = 0;
|
||||||
|
|
||||||
int n;
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
pingc = 0;
|
pingc = 0;
|
||||||
for (i = 1; i < MAXPLAYERS; ++i)
|
for (INT32 i = 1; i < MAXPLAYERS; ++i)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
{
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
n = strlen(player_names[i]);
|
n = strlen(player_names[i]);
|
||||||
if (n > name_width)
|
if (n > name_width)
|
||||||
name_width = n;
|
name_width = n;
|
||||||
|
@ -1425,7 +1359,7 @@ void Command_Ping_f(void)
|
||||||
|
|
||||||
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
||||||
|
|
||||||
for (i = 0; i < pingc; ++i)
|
for (INT32 i = 0; i < pingc; ++i)
|
||||||
{
|
{
|
||||||
CONS_Printf("%02d : %-*s %*d ms\n",
|
CONS_Printf("%02d : %-*s %*d ms\n",
|
||||||
pingv[i].num,
|
pingv[i].num,
|
||||||
|
@ -1441,15 +1375,13 @@ void Command_Ping_f(void)
|
||||||
|
|
||||||
void D_CloseConnection(void)
|
void D_CloseConnection(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
{
|
{
|
||||||
// wait the ackreturn with timout of 5 Sec
|
// wait the ackreturn with timout of 5 Sec
|
||||||
Net_WaitAllAckReceived(5);
|
Net_WaitAllAckReceived(5);
|
||||||
|
|
||||||
// close all connection
|
// close all connection
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
Net_CloseConnection(i|FORCECLOSE);
|
Net_CloseConnection(i|FORCECLOSE);
|
||||||
|
|
||||||
InitAck();
|
InitAck();
|
|
@ -18,6 +18,8 @@
|
||||||
#ifndef __D_NET__
|
#ifndef __D_NET__
|
||||||
#define __D_NET__
|
#define __D_NET__
|
||||||
|
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
// Max computers in a game
|
// Max computers in a game
|
||||||
// 127 is probably as high as this can go, because
|
// 127 is probably as high as this can go, because
|
||||||
// SINT8 is used for nodes sometimes >:(
|
// SINT8 is used for nodes sometimes >:(
|
||||||
|
@ -37,10 +39,24 @@ boolean Net_GetNetStat(void);
|
||||||
extern INT32 getbytes;
|
extern INT32 getbytes;
|
||||||
extern INT64 sendbytes; // Realtime updated
|
extern INT64 sendbytes; // Realtime updated
|
||||||
|
|
||||||
extern SINT8 nodetoplayer[MAXNETNODES];
|
typedef struct netnode_s
|
||||||
extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if any (splitscreen)
|
{
|
||||||
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
boolean ingame; // set false as nodes leave game
|
||||||
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
tic_t freezetimeout; // Until when can this node freeze the server before getting a timeout?
|
||||||
|
|
||||||
|
SINT8 player;
|
||||||
|
SINT8 player2; // say the numplayer for this node if any (splitscreen)
|
||||||
|
UINT8 numplayers; // used specialy for scplitscreen
|
||||||
|
|
||||||
|
tic_t tic; // what tic the client have received
|
||||||
|
tic_t supposedtic; // nettics prevision for smaller packet
|
||||||
|
|
||||||
|
boolean sendingsavegame; // Are we sending the savegame?
|
||||||
|
boolean resendingsavegame; // Are we resending the savegame?
|
||||||
|
tic_t savegameresendcooldown; // How long before we can resend again?
|
||||||
|
} netnode_t;
|
||||||
|
|
||||||
|
extern netnode_t netnodes[MAXNETNODES];
|
||||||
|
|
||||||
extern boolean serverrunning;
|
extern boolean serverrunning;
|
||||||
|
|
||||||
|
@ -52,9 +68,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum,
|
||||||
size_t packetlength);
|
size_t packetlength);
|
||||||
boolean HGetPacket(void);
|
boolean HGetPacket(void);
|
||||||
void D_SetDoomcom(void);
|
void D_SetDoomcom(void);
|
||||||
#ifndef NONET
|
|
||||||
void D_SaveBan(void);
|
|
||||||
#endif
|
|
||||||
boolean D_CheckNetGame(void);
|
boolean D_CheckNetGame(void);
|
||||||
void D_CloseConnection(void);
|
void D_CloseConnection(void);
|
||||||
void Net_UnAcknowledgePacket(INT32 node);
|
void Net_UnAcknowledgePacket(INT32 node);
|
|
@ -12,44 +12,46 @@
|
||||||
/// commands are executed through the command buffer
|
/// commands are executed through the command buffer
|
||||||
/// like console commands, other miscellaneous commands (at the end)
|
/// like console commands, other miscellaneous commands (at the end)
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
|
|
||||||
#include "console.h"
|
#include "../console.h"
|
||||||
#include "command.h"
|
#include "../command.h"
|
||||||
#include "i_time.h"
|
#include "../i_time.h"
|
||||||
#include "i_system.h"
|
#include "../i_system.h"
|
||||||
#include "g_game.h"
|
#include "../g_game.h"
|
||||||
#include "hu_stuff.h"
|
#include "../hu_stuff.h"
|
||||||
#include "g_input.h"
|
#include "../g_input.h"
|
||||||
#include "m_menu.h"
|
#include "../m_menu.h"
|
||||||
#include "r_local.h"
|
#include "../r_local.h"
|
||||||
#include "r_skins.h"
|
#include "../r_skins.h"
|
||||||
#include "p_local.h"
|
#include "../p_local.h"
|
||||||
#include "p_setup.h"
|
#include "../p_setup.h"
|
||||||
#include "s_sound.h"
|
#include "../s_sound.h"
|
||||||
#include "i_sound.h"
|
#include "../i_sound.h"
|
||||||
#include "m_misc.h"
|
#include "../m_misc.h"
|
||||||
#include "am_map.h"
|
#include "../am_map.h"
|
||||||
#include "byteptr.h"
|
#include "../byteptr.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "p_spec.h"
|
#include "../p_spec.h"
|
||||||
#include "m_cheat.h"
|
#include "../m_cheat.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
|
#include "server_connection.h"
|
||||||
|
#include "net_command.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "v_video.h"
|
#include "../v_video.h"
|
||||||
#include "d_main.h"
|
#include "../d_main.h"
|
||||||
#include "m_random.h"
|
#include "../m_random.h"
|
||||||
#include "f_finale.h"
|
#include "../f_finale.h"
|
||||||
#include "filesrch.h"
|
#include "../filesrch.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "z_zone.h"
|
#include "../z_zone.h"
|
||||||
#include "lua_script.h"
|
#include "../lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "../lua_hook.h"
|
||||||
#include "m_cond.h"
|
#include "../m_cond.h"
|
||||||
#include "m_anigif.h"
|
#include "../m_anigif.h"
|
||||||
#include "md5.h"
|
#include "../md5.h"
|
||||||
#include "m_perfstats.h"
|
#include "../m_perfstats.h"
|
||||||
#include "u_list.h"
|
#include "../u_list.h"
|
||||||
|
|
||||||
#ifdef NETGAME_DEVMODE
|
#ifdef NETGAME_DEVMODE
|
||||||
#define CV_RESTRICT CV_NETVAR
|
#define CV_RESTRICT CV_NETVAR
|
||||||
|
@ -225,6 +227,7 @@ consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE|CV_ALLOWLUA,
|
||||||
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
|
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
|
||||||
|
|
||||||
// names
|
// names
|
||||||
|
static char *lastskinnames[2];
|
||||||
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
|
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
|
||||||
consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
||||||
// player colors
|
// player colors
|
||||||
|
@ -594,13 +597,10 @@ void D_RegisterServerCommands(void)
|
||||||
CV_RegisterVar(&cv_maxsend);
|
CV_RegisterVar(&cv_maxsend);
|
||||||
CV_RegisterVar(&cv_noticedownload);
|
CV_RegisterVar(&cv_noticedownload);
|
||||||
CV_RegisterVar(&cv_downloadspeed);
|
CV_RegisterVar(&cv_downloadspeed);
|
||||||
#ifndef NONET
|
|
||||||
CV_RegisterVar(&cv_allownewplayer);
|
CV_RegisterVar(&cv_allownewplayer);
|
||||||
CV_RegisterVar(&cv_joinnextround);
|
|
||||||
CV_RegisterVar(&cv_showjoinaddress);
|
CV_RegisterVar(&cv_showjoinaddress);
|
||||||
CV_RegisterVar(&cv_blamecfail);
|
CV_RegisterVar(&cv_blamecfail);
|
||||||
CV_RegisterVar(&cv_dedicatedidletime);
|
CV_RegisterVar(&cv_dedicatedidletime);
|
||||||
#endif
|
|
||||||
|
|
||||||
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
||||||
CV_RegisterVar(&cv_nettimeout);
|
CV_RegisterVar(&cv_nettimeout);
|
||||||
|
@ -776,6 +776,8 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_showfocuslost);
|
CV_RegisterVar(&cv_showfocuslost);
|
||||||
CV_RegisterVar(&cv_pauseifunfocused);
|
CV_RegisterVar(&cv_pauseifunfocused);
|
||||||
|
|
||||||
|
CV_RegisterVar(&cv_instantretry);
|
||||||
|
|
||||||
// g_input.c
|
// g_input.c
|
||||||
CV_RegisterVar(&cv_sideaxis);
|
CV_RegisterVar(&cv_sideaxis);
|
||||||
CV_RegisterVar(&cv_sideaxis2);
|
CV_RegisterVar(&cv_sideaxis2);
|
||||||
|
@ -1203,27 +1205,38 @@ UINT8 CanChangeSkin(INT32 playernum)
|
||||||
|
|
||||||
static void ForceAllSkins(INT32 forcedskin)
|
static void ForceAllSkins(INT32 forcedskin)
|
||||||
{
|
{
|
||||||
INT32 i;
|
for (INT32 i = 0; i < MAXPLAYERS; ++i)
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (playeringame[i])
|
||||||
continue;
|
SetPlayerSkinByNum(i, forcedskin);
|
||||||
|
|
||||||
SetPlayerSkinByNum(i, forcedskin);
|
|
||||||
|
|
||||||
// If it's me (or my brother), set appropriate skin value in cv_skin/cv_skin2
|
|
||||||
if (!dedicated) // But don't do this for dedicated servers, of course.
|
|
||||||
{
|
|
||||||
if (i == consoleplayer)
|
|
||||||
CV_StealthSet(&cv_skin, skins[forcedskin].name);
|
|
||||||
else if (i == secondarydisplayplayer)
|
|
||||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT32 snacpending = 0, snac2pending = 0, chmappending = 0;
|
static INT32 snacpending = 0, snac2pending = 0, chmappending = 0;
|
||||||
|
|
||||||
|
static void SetSkinLocal(INT32 playernum, INT32 skinnum)
|
||||||
|
{
|
||||||
|
if (metalrecording && playernum == consoleplayer)
|
||||||
|
{
|
||||||
|
// Starring Metal Sonic as themselves, obviously.
|
||||||
|
SetPlayerSkinByNum(playernum, 5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skinnum != -1 && R_SkinUsable(playernum, skinnum))
|
||||||
|
SetPlayerSkinByNum(playernum, skinnum);
|
||||||
|
else
|
||||||
|
SetPlayerSkinByNum(playernum, GetPlayerDefaultSkin(playernum));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetColorLocal(INT32 playernum, UINT16 color)
|
||||||
|
{
|
||||||
|
players[playernum].skincolor = color;
|
||||||
|
|
||||||
|
if (players[playernum].mo && !players[playernum].powers[pw_dye])
|
||||||
|
players[playernum].mo->color = P_GetPlayerColor(&players[playernum]);
|
||||||
|
}
|
||||||
|
|
||||||
// name, color, or skin has changed
|
// name, color, or skin has changed
|
||||||
//
|
//
|
||||||
static void SendNameAndColor(void)
|
static void SendNameAndColor(void)
|
||||||
|
@ -1233,15 +1246,6 @@ static void SendNameAndColor(void)
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
|
|
||||||
// normal player colors
|
|
||||||
if (G_GametypeHasTeams())
|
|
||||||
{
|
|
||||||
if (players[consoleplayer].ctfteam == 1 && cv_playercolor.value != skincolor_redteam)
|
|
||||||
CV_StealthSetValue(&cv_playercolor, skincolor_redteam);
|
|
||||||
else if (players[consoleplayer].ctfteam == 2 && cv_playercolor.value != skincolor_blueteam)
|
|
||||||
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't allow inaccessible colors
|
// don't allow inaccessible colors
|
||||||
if (!skincolors[cv_playercolor.value].accessible)
|
if (!skincolors[cv_playercolor.value].accessible)
|
||||||
{
|
{
|
||||||
|
@ -1272,50 +1276,15 @@ static void SendNameAndColor(void)
|
||||||
// If you're not in a netgame, merely update the skin, color, and name.
|
// If you're not in a netgame, merely update the skin, color, and name.
|
||||||
if (!netgame)
|
if (!netgame)
|
||||||
{
|
{
|
||||||
INT32 foundskin;
|
|
||||||
|
|
||||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||||
strcpy(player_names[consoleplayer], cv_playername.zstring);
|
strcpy(player_names[consoleplayer], cv_playername.zstring);
|
||||||
|
|
||||||
players[consoleplayer].skincolor = cv_playercolor.value;
|
SetColorLocal(consoleplayer, cv_playercolor.value);
|
||||||
|
|
||||||
if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
|
if (splitscreen)
|
||||||
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
|
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
||||||
|
|
||||||
if (metalrecording)
|
|
||||||
{ // Starring Metal Sonic as themselves, obviously.
|
|
||||||
SetPlayerSkinByNum(consoleplayer, 5);
|
|
||||||
CV_StealthSet(&cv_skin, skins[5].name);
|
|
||||||
}
|
|
||||||
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin))
|
|
||||||
{
|
|
||||||
//boolean notsame;
|
|
||||||
|
|
||||||
cv_skin.value = foundskin;
|
|
||||||
|
|
||||||
//notsame = (cv_skin.value != players[consoleplayer].skin);
|
|
||||||
|
|
||||||
SetPlayerSkin(consoleplayer, cv_skin.string);
|
|
||||||
CV_StealthSet(&cv_skin, skins[cv_skin.value].name);
|
|
||||||
|
|
||||||
/*if (notsame)
|
|
||||||
{
|
|
||||||
CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor);
|
|
||||||
|
|
||||||
players[consoleplayer].skincolor = cv_playercolor.value % numskincolors;
|
|
||||||
|
|
||||||
if (players[consoleplayer].mo)
|
|
||||||
players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
SetSkinLocal(consoleplayer, pickedchar);
|
||||||
cv_skin.value = players[consoleplayer].skin;
|
|
||||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
|
||||||
// will always be same as current
|
|
||||||
SetPlayerSkin(consoleplayer, cv_skin.string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,10 +1301,6 @@ static void SendNameAndColor(void)
|
||||||
else // Cleanup name if changing it
|
else // Cleanup name if changing it
|
||||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||||
|
|
||||||
// Don't change skin if the server doesn't want you to.
|
|
||||||
if (!CanChangeSkin(consoleplayer))
|
|
||||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
|
||||||
|
|
||||||
// check if player has the skin loaded (cv_skin may have
|
// check if player has the skin loaded (cv_skin may have
|
||||||
// the name of a skin that was available in the previous game)
|
// the name of a skin that was available in the previous game)
|
||||||
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
||||||
|
@ -1367,16 +1332,6 @@ static void SendNameAndColor2(void)
|
||||||
else // HACK
|
else // HACK
|
||||||
secondplaya = 1;
|
secondplaya = 1;
|
||||||
|
|
||||||
// normal player colors
|
|
||||||
if (G_GametypeHasTeams())
|
|
||||||
{
|
|
||||||
if (players[secondplaya].ctfteam == 1 && cv_playercolor2.value != skincolor_redteam)
|
|
||||||
CV_StealthSetValue(&cv_playercolor2, skincolor_redteam);
|
|
||||||
else if (players[secondplaya].ctfteam == 2 && cv_playercolor2.value != skincolor_blueteam)
|
|
||||||
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't allow inaccessible colors
|
|
||||||
if (!skincolors[cv_playercolor2.value].accessible)
|
if (!skincolors[cv_playercolor2.value].accessible)
|
||||||
{
|
{
|
||||||
if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible)
|
if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible)
|
||||||
|
@ -1398,63 +1353,24 @@ static void SendNameAndColor2(void)
|
||||||
if (!Playing())
|
if (!Playing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If you're not in a netgame, merely update the skin, color, and name.
|
|
||||||
if (botingame)
|
if (botingame)
|
||||||
{
|
{
|
||||||
players[secondplaya].skincolor = botcolor;
|
SetColorLocal(secondplaya, botcolor);
|
||||||
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
|
|
||||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
|
||||||
|
|
||||||
SetPlayerSkinByNum(secondplaya, botskin-1);
|
SetPlayerSkinByNum(secondplaya, botskin-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!netgame)
|
else if (!netgame)
|
||||||
{
|
{
|
||||||
INT32 foundskin;
|
// If you're not in a netgame, merely update the skin, color, and name.
|
||||||
|
|
||||||
CleanupPlayerName(secondplaya, cv_playername2.zstring);
|
CleanupPlayerName(secondplaya, cv_playername2.zstring);
|
||||||
strcpy(player_names[secondplaya], cv_playername2.zstring);
|
strcpy(player_names[secondplaya], cv_playername2.zstring);
|
||||||
|
|
||||||
// don't use secondarydisplayplayer: the second player must be 1
|
SetColorLocal(secondplaya, cv_playercolor2.value);
|
||||||
players[secondplaya].skincolor = cv_playercolor2.value;
|
|
||||||
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
|
|
||||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
|
||||||
|
|
||||||
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
|
if (cv_forceskin.value >= 0)
|
||||||
{
|
SetSkinLocal(secondplaya, cv_forceskin.value);
|
||||||
const INT32 forcedskin = cv_forceskin.value;
|
|
||||||
|
|
||||||
SetPlayerSkinByNum(secondplaya, forcedskin);
|
|
||||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
|
||||||
}
|
|
||||||
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin))
|
|
||||||
{
|
|
||||||
//boolean notsame;
|
|
||||||
|
|
||||||
cv_skin2.value = foundskin;
|
|
||||||
|
|
||||||
//notsame = (cv_skin2.value != players[secondplaya].skin);
|
|
||||||
|
|
||||||
SetPlayerSkin(secondplaya, cv_skin2.string);
|
|
||||||
CV_StealthSet(&cv_skin2, skins[cv_skin2.value].name);
|
|
||||||
|
|
||||||
/*if (notsame)
|
|
||||||
{
|
|
||||||
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
|
|
||||||
|
|
||||||
players[secondplaya].skincolor = cv_playercolor2.value % numskincolors;
|
|
||||||
|
|
||||||
if (players[secondplaya].mo)
|
|
||||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
SetSkinLocal(secondplaya, R_SkinAvailable(cv_skin2.string));
|
||||||
cv_skin2.value = players[secondplaya].skin;
|
|
||||||
CV_StealthSet(&cv_skin2, skins[players[secondplaya].skin].name);
|
|
||||||
// will always be same as current
|
|
||||||
SetPlayerSkin(secondplaya, cv_skin2.string);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,7 +1414,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
// set color
|
// set color
|
||||||
p->skincolor = color % numskincolors;
|
p->skincolor = color % numskincolors;
|
||||||
if (p->mo)
|
if (p->mo)
|
||||||
p->mo->color = (UINT16)p->skincolor;
|
p->mo->color = P_GetPlayerColor(p);
|
||||||
|
|
||||||
// normal player colors
|
// normal player colors
|
||||||
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
|
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
|
||||||
|
@ -1507,15 +1423,6 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
UINT32 unlockShift = 0;
|
UINT32 unlockShift = 0;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
|
|
||||||
// team colors
|
|
||||||
if (G_GametypeHasTeams())
|
|
||||||
{
|
|
||||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
|
||||||
kick = true;
|
|
||||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
|
||||||
kick = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't allow inaccessible colors
|
// don't allow inaccessible colors
|
||||||
if (skincolors[p->skincolor].accessible == false)
|
if (skincolors[p->skincolor].accessible == false)
|
||||||
kick = true;
|
kick = true;
|
||||||
|
@ -1556,16 +1463,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set skin
|
// set skin
|
||||||
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
|
INT32 forcedskin = R_GetForcedSkin(playernum);
|
||||||
{
|
if (forcedskin != -1 && (netgame || multiplayer)) // Server wants everyone to use the same player (or the level is forcing one.)
|
||||||
const INT32 forcedskin = cv_forceskin.value;
|
|
||||||
SetPlayerSkinByNum(playernum, forcedskin);
|
SetPlayerSkinByNum(playernum, forcedskin);
|
||||||
|
|
||||||
if (playernum == consoleplayer)
|
|
||||||
CV_StealthSet(&cv_skin, skins[forcedskin].name);
|
|
||||||
else if (playernum == secondarydisplayplayer)
|
|
||||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
SetPlayerSkinByNum(playernum, skin);
|
SetPlayerSkinByNum(playernum, skin);
|
||||||
}
|
}
|
||||||
|
@ -1841,8 +1741,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
||||||
// reset players if there is a new one
|
// reset players if there is a new one
|
||||||
if (!IsPlayerAdmin(consoleplayer))
|
if (!IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
if (SV_SpawnServer())
|
SV_SpawnServer();
|
||||||
buf[0] &= ~(1<<1);
|
|
||||||
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1902,8 +1801,8 @@ static void Command_Map_f(void)
|
||||||
size_t option_gametype;
|
size_t option_gametype;
|
||||||
const char *gametypename;
|
const char *gametypename;
|
||||||
boolean newresetplayers;
|
boolean newresetplayers;
|
||||||
|
boolean prevent_cheat;
|
||||||
boolean wouldSetCheats;
|
boolean set_cheated;
|
||||||
|
|
||||||
INT32 newmapnum;
|
INT32 newmapnum;
|
||||||
|
|
||||||
|
@ -1924,21 +1823,34 @@ static void Command_Map_f(void)
|
||||||
option_gametype = COM_CheckPartialParm("-g");
|
option_gametype = COM_CheckPartialParm("-g");
|
||||||
newresetplayers = ! COM_CheckParm("-noresetplayers");
|
newresetplayers = ! COM_CheckParm("-noresetplayers");
|
||||||
|
|
||||||
wouldSetCheats =
|
prevent_cheat = !( usedCheats ) && !( option_force || cv_debug );
|
||||||
!( netgame || multiplayer ) &&
|
set_cheated = false;
|
||||||
!( usedCheats );
|
|
||||||
|
|
||||||
if (wouldSetCheats && !option_force)
|
if (!( netgame || multiplayer ))
|
||||||
{
|
{
|
||||||
/* May want to be more descriptive? */
|
if (prevent_cheat)
|
||||||
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
{
|
||||||
return;
|
/* May want to be more descriptive? */
|
||||||
|
CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_cheated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newresetplayers && !cv_debug)
|
if (!newresetplayers)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("DEVMODE must be enabled.\n"));
|
if (prevent_cheat)
|
||||||
return;
|
{
|
||||||
|
CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_cheated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_gametype)
|
if (option_gametype)
|
||||||
|
@ -1946,7 +1858,7 @@ static void Command_Map_f(void)
|
||||||
if (!multiplayer)
|
if (!multiplayer)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText(
|
CONS_Printf(M_GetText(
|
||||||
"You can't switch gametypes in single player!\n"));
|
"You can't switch gametypes in single player!\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (COM_Argc() < option_gametype + 2)/* no argument after? */
|
else if (COM_Argc() < option_gametype + 2)/* no argument after? */
|
||||||
|
@ -1959,7 +1871,9 @@ static void Command_Map_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!( first_option = COM_FirstOption() ))
|
if (!( first_option = COM_FirstOption() ))
|
||||||
|
{
|
||||||
first_option = COM_Argc();
|
first_option = COM_Argc();
|
||||||
|
}
|
||||||
|
|
||||||
if (first_option < 2)
|
if (first_option < 2)
|
||||||
{
|
{
|
||||||
|
@ -1982,11 +1896,6 @@ static void Command_Map_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wouldSetCheats && option_force)
|
|
||||||
{
|
|
||||||
G_SetUsedCheats(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// new gametype value
|
// new gametype value
|
||||||
// use current one by default
|
// use current one by default
|
||||||
if (option_gametype)
|
if (option_gametype)
|
||||||
|
@ -2028,15 +1937,13 @@ static void Command_Map_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use a gametype the map doesn't support
|
// don't use a gametype the map doesn't support
|
||||||
if (cv_debug || option_force || cv_skipmapcheck.value)
|
|
||||||
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
|
|
||||||
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
||||||
else
|
if (!(
|
||||||
|
mapheaderinfo[newmapnum-1] &&
|
||||||
|
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
|
||||||
|
))
|
||||||
{
|
{
|
||||||
if (!(
|
if (prevent_cheat && !cv_skipmapcheck.value)
|
||||||
mapheaderinfo[newmapnum-1] &&
|
|
||||||
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
|
|
||||||
))
|
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
|
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
|
||||||
(multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
|
(multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
|
||||||
|
@ -2046,23 +1953,33 @@ static void Command_Map_f(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fromlevelselect =
|
// The player wants us to trek on anyway. Do so.
|
||||||
( netgame || multiplayer ) &&
|
fromlevelselect = false;
|
||||||
newgametype == gametype &&
|
set_cheated = ((gametypedefaultrules[newgametype] & GTR_CAMPAIGN) == GTR_CAMPAIGN);
|
||||||
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fromlevelselect =
|
||||||
|
( netgame || multiplayer ) &&
|
||||||
|
newgametype == gametype &&
|
||||||
|
(gametypedefaultrules[newgametype] & GTR_CAMPAIGN);
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent warping to locked levels
|
// Prevent warping to locked levels
|
||||||
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
|
if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata))
|
||||||
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
|
|
||||||
// lives hell.
|
|
||||||
if (!dedicated && M_MapLocked(newmapnum, serverGamedata))
|
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
|
if (prevent_cheat)
|
||||||
Z_Free(realmapname);
|
{
|
||||||
Z_Free(mapname);
|
CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to warp to a locked level!\n"));
|
||||||
return;
|
Z_Free(realmapname);
|
||||||
|
Z_Free(mapname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_cheated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ultimate Mode only in SP via menu
|
// Ultimate Mode only in SP via menu
|
||||||
|
@ -2079,6 +1996,11 @@ static void Command_Map_f(void)
|
||||||
}
|
}
|
||||||
tutorialmode = false; // warping takes us out of tutorial mode
|
tutorialmode = false; // warping takes us out of tutorial mode
|
||||||
|
|
||||||
|
if (set_cheated && !usedCheats)
|
||||||
|
{
|
||||||
|
G_SetUsedCheats(false);
|
||||||
|
}
|
||||||
|
|
||||||
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
||||||
|
|
||||||
Z_Free(realmapname);
|
Z_Free(realmapname);
|
||||||
|
@ -2120,11 +2042,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
lastgametype = gametype;
|
lastgametype = gametype;
|
||||||
gametype = READUINT8(*cp);
|
gametype = READUINT8(*cp);
|
||||||
G_SetGametype(gametype); // I fear putting that macro as an argument
|
|
||||||
|
|
||||||
if (gametype < 0 || gametype >= gametypecount)
|
if (gametype < 0 || gametype >= gametypecount)
|
||||||
gametype = lastgametype;
|
gametype = lastgametype;
|
||||||
else if (gametype != lastgametype)
|
else
|
||||||
|
G_SetGametype(gametype);
|
||||||
|
|
||||||
|
if (gametype != lastgametype)
|
||||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||||
|
|
||||||
skipprecutscene = ((flags & (1<<2)) != 0);
|
skipprecutscene = ((flags & (1<<2)) != 0);
|
||||||
|
@ -2150,7 +2074,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
||||||
players[0].skincolor = skins[players[0].skin].prefcolor;
|
players[0].skincolor = skins[players[0].skin].prefcolor;
|
||||||
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||||
|
@ -2904,17 +2827,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
displayplayer = consoleplayer;
|
displayplayer = consoleplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_GametypeHasTeams())
|
|
||||||
{
|
|
||||||
if (NetPacket.packet.newteam)
|
|
||||||
{
|
|
||||||
if (playernum == consoleplayer) //CTF and Team Match colors.
|
|
||||||
CV_SetValue(&cv_playercolor, NetPacket.packet.newteam + 5);
|
|
||||||
else if (playernum == secondarydisplayplayer)
|
|
||||||
CV_SetValue(&cv_playercolor2, NetPacket.packet.newteam + 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In tag, check to see if you still have a game.
|
// In tag, check to see if you still have a game.
|
||||||
if (G_TagGametype())
|
if (G_TagGametype())
|
||||||
P_CheckSurvivors();
|
P_CheckSurvivors();
|
||||||
|
@ -4252,9 +4164,6 @@ void D_GameTypeChanged(INT32 lastgametype)
|
||||||
else if (!multiplayer && !netgame)
|
else if (!multiplayer && !netgame)
|
||||||
{
|
{
|
||||||
G_SetGametype(GT_COOP);
|
G_SetGametype(GT_COOP);
|
||||||
// These shouldn't matter anymore
|
|
||||||
//CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue);
|
|
||||||
//CV_SetValue(&cv_itemrespawn, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
|
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
|
||||||
|
@ -4555,25 +4464,37 @@ static void Command_Mapmd5_f(void)
|
||||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D_SendExitLevel(boolean cheat)
|
||||||
|
{
|
||||||
|
UINT8 buf[8];
|
||||||
|
UINT8 *buf_p = buf;
|
||||||
|
|
||||||
|
WRITEUINT8(buf_p, cheat);
|
||||||
|
|
||||||
|
SendNetXCmd(XD_EXITLEVEL, &buf, buf_p - buf);
|
||||||
|
}
|
||||||
|
|
||||||
static void Command_ExitLevel_f(void)
|
static void Command_ExitLevel_f(void)
|
||||||
{
|
{
|
||||||
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
|
||||||
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
|
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
|
||||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||||
else
|
else
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
(void)cp;
|
boolean cheat = false;
|
||||||
|
|
||||||
|
cheat = (boolean)READUINT8(*cp);
|
||||||
|
|
||||||
// Ignore duplicate XD_EXITLEVEL commands.
|
// Ignore duplicate XD_EXITLEVEL commands.
|
||||||
if (gameaction == ga_completed)
|
if (gameaction == ga_completed)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
|
@ -4583,6 +4504,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (G_CoopGametype() && cheat)
|
||||||
|
{
|
||||||
|
G_SetUsedCheats(false);
|
||||||
|
}
|
||||||
|
|
||||||
G_ExitLevel();
|
G_ExitLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4779,11 +4705,16 @@ static void ForceSkin_OnChange(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cv_forceskin.value < 0)
|
if (cv_forceskin.value < 0)
|
||||||
|
{
|
||||||
CONS_Printf("The server has lifted the forced skin restrictions.\n");
|
CONS_Printf("The server has lifted the forced skin restrictions.\n");
|
||||||
|
if (Playing())
|
||||||
|
D_SendPlayerConfig();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
|
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
|
||||||
ForceAllSkins(cv_forceskin.value);
|
if (Playing())
|
||||||
|
ForceAllSkins(cv_forceskin.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4797,7 +4728,6 @@ static void Name_OnChange(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendNameAndColor();
|
SendNameAndColor();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Name2_OnChange(void)
|
static void Name2_OnChange(void)
|
||||||
|
@ -4820,19 +4750,33 @@ static void Skin_OnChange(void)
|
||||||
if (!Playing())
|
if (!Playing())
|
||||||
return; // do whatever you want
|
return; // do whatever you want
|
||||||
|
|
||||||
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
|
if (lastskinnames[0] == NULL)
|
||||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
||||||
|
|
||||||
|
if (!(multiplayer || netgame)) // In single player.
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
if (!(cv_debug || devparm)
|
||||||
|
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just do it here if devmode is enabled
|
||||||
|
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
||||||
|
{
|
||||||
SendNameAndColor();
|
SendNameAndColor();
|
||||||
|
Z_Free(lastskinnames[0]);
|
||||||
|
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
CV_StealthSet(&cv_skin, lastskinnames[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4846,12 +4790,19 @@ static void Skin2_OnChange(void)
|
||||||
if (!Playing() || !splitscreen)
|
if (!Playing() || !splitscreen)
|
||||||
return; // do whatever you want
|
return; // do whatever you want
|
||||||
|
|
||||||
|
if (lastskinnames[1] == NULL)
|
||||||
|
lastskinnames[1] = Z_StrDup(cv_skin2.string);
|
||||||
|
|
||||||
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
|
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
|
||||||
|
{
|
||||||
SendNameAndColor2();
|
SendNameAndColor2();
|
||||||
|
Z_Free(lastskinnames[1]);
|
||||||
|
lastskinnames[1] = Z_StrDup(cv_skin.string);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||||
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
|
CV_StealthSet(&cv_skin2, lastskinnames[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4861,15 +4812,18 @@ static void Skin2_OnChange(void)
|
||||||
*/
|
*/
|
||||||
static void Color_OnChange(void)
|
static void Color_OnChange(void)
|
||||||
{
|
{
|
||||||
if (!Playing()) {
|
if (!Playing())
|
||||||
|
{
|
||||||
if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible)
|
if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible)
|
||||||
CV_StealthSetValue(&cv_playercolor, lastgoodcolor);
|
CV_StealthSetValue(&cv_playercolor, lastgoodcolor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
|
if (!(multiplayer || netgame)) // In single player.
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
// Just do it here if devmode is enabled
|
||||||
|
if (cv_debug || devparm)
|
||||||
|
SetColorLocal(consoleplayer, cv_playercolor.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#ifndef __D_NETCMD__
|
#ifndef __D_NETCMD__
|
||||||
#define __D_NETCMD__
|
#define __D_NETCMD__
|
||||||
|
|
||||||
#include "command.h"
|
#include "../command.h"
|
||||||
|
|
||||||
// console vars
|
// console vars
|
||||||
extern consvar_t cv_playername;
|
extern consvar_t cv_playername;
|
||||||
|
@ -201,6 +201,7 @@ void D_SendPlayerConfig(void);
|
||||||
void Command_ExitGame_f(void);
|
void Command_ExitGame_f(void);
|
||||||
void Command_Retry_f(void);
|
void Command_Retry_f(void);
|
||||||
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
||||||
|
void D_SendExitLevel(boolean cheat);
|
||||||
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
|
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
|
||||||
boolean IsPlayerAdmin(INT32 playernum);
|
boolean IsPlayerAdmin(INT32 playernum);
|
||||||
void SetAdminPlayer(INT32 playernum);
|
void SetAdminPlayer(INT32 playernum);
|
|
@ -31,24 +31,25 @@
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "../doomstat.h"
|
||||||
#include "d_main.h"
|
#include "../d_main.h"
|
||||||
#include "g_game.h"
|
#include "../g_game.h"
|
||||||
#include "i_time.h"
|
#include "../i_time.h"
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
#include "i_system.h"
|
#include "../i_system.h"
|
||||||
#include "m_argv.h"
|
#include "../m_argv.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "w_wad.h"
|
#include "../w_wad.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "z_zone.h"
|
#include "net_command.h"
|
||||||
#include "byteptr.h"
|
#include "../z_zone.h"
|
||||||
#include "p_setup.h"
|
#include "../byteptr.h"
|
||||||
#include "m_misc.h"
|
#include "../p_setup.h"
|
||||||
#include "m_menu.h"
|
#include "../m_misc.h"
|
||||||
#include "md5.h"
|
#include "../m_menu.h"
|
||||||
#include "filesrch.h"
|
#include "../md5.h"
|
||||||
|
#include "../filesrch.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -103,26 +104,31 @@ typedef struct
|
||||||
} pauseddownload_t;
|
} pauseddownload_t;
|
||||||
static pauseddownload_t *pauseddownload = NULL;
|
static pauseddownload_t *pauseddownload = NULL;
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// for cl loading screen
|
// for cl loading screen
|
||||||
INT32 lastfilenum = -1;
|
INT32 lastfilenum = -1;
|
||||||
INT32 downloadcompletednum = 0;
|
INT32 downloadcompletednum = 0;
|
||||||
UINT32 downloadcompletedsize = 0;
|
UINT32 downloadcompletedsize = 0;
|
||||||
INT32 totalfilesrequestednum = 0;
|
INT32 totalfilesrequestednum = 0;
|
||||||
UINT32 totalfilesrequestedsize = 0;
|
UINT32 totalfilesrequestedsize = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
luafiletransfer_t *luafiletransfers = NULL;
|
luafiletransfer_t *luafiletransfers = NULL;
|
||||||
boolean waitingforluafiletransfer = false;
|
boolean waitingforluafiletransfer = false;
|
||||||
boolean waitingforluafilecommand = false;
|
boolean waitingforluafilecommand = false;
|
||||||
char luafiledir[256 + 16] = "luafiles";
|
char luafiledir[256 + 16] = "luafiles";
|
||||||
|
|
||||||
|
// max file size to send to a player (in kilobytes)
|
||||||
|
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {204800, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL);
|
||||||
|
|
||||||
|
consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
// Speed of file downloading (in packets per tic)
|
||||||
|
static CV_PossibleValue_t downloadspeed_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL);
|
||||||
|
|
||||||
static UINT16 GetWadNumFromFileNeededId(UINT8 id)
|
static UINT16 GetWadNumFromFileNeededId(UINT8 id)
|
||||||
{
|
{
|
||||||
UINT16 wadnum;
|
for (UINT16 wadnum = mainwads; wadnum < numwadfiles; wadnum++)
|
||||||
|
|
||||||
for (wadnum = mainwads; wadnum < numwadfiles; wadnum++)
|
|
||||||
{
|
{
|
||||||
if (!wadfiles[wadnum]->important)
|
if (!wadfiles[wadnum]->important)
|
||||||
continue;
|
continue;
|
||||||
|
@ -142,14 +148,13 @@ static UINT16 GetWadNumFromFileNeededId(UINT8 id)
|
||||||
*/
|
*/
|
||||||
UINT8 *PutFileNeeded(UINT16 firstfile)
|
UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
UINT8 count = 0;
|
UINT8 count = 0;
|
||||||
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
|
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
|
||||||
UINT8 *p = p_start;
|
UINT8 *p = p_start;
|
||||||
char wadfilename[MAX_WADPATH] = "";
|
char wadfilename[MAX_WADPATH] = "";
|
||||||
UINT8 filestatus, folder;
|
UINT8 filestatus, folder;
|
||||||
|
|
||||||
for (i = mainwads; i < numwadfiles; i++) //mainwads, otherwise we start on the first mainwad
|
for (size_t i = mainwads; i < numwadfiles; i++) //mainwads, otherwise we start on the first mainwad
|
||||||
{
|
{
|
||||||
// If it has only music/sound lumps, don't put it in the list
|
// If it has only music/sound lumps, don't put it in the list
|
||||||
if (!wadfiles[i]->important)
|
if (!wadfiles[i]->important)
|
||||||
|
@ -224,7 +229,6 @@ void FreeFileNeeded(void)
|
||||||
*/
|
*/
|
||||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile)
|
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
UINT8 *p;
|
UINT8 *p;
|
||||||
UINT8 filestatus;
|
UINT8 filestatus;
|
||||||
|
|
||||||
|
@ -233,7 +237,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
||||||
|
|
||||||
AllocFileNeeded(fileneedednum);
|
AllocFileNeeded(fileneedednum);
|
||||||
|
|
||||||
for (i = firstfile; i < fileneedednum; i++)
|
for (INT32 i = firstfile; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
fileneeded[i].type = FILENEEDED_WAD;
|
fileneeded[i].type = FILENEEDED_WAD;
|
||||||
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
|
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
|
||||||
|
@ -250,9 +254,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
||||||
|
|
||||||
void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
lastfilenum = -1;
|
lastfilenum = -1;
|
||||||
#endif
|
|
||||||
|
|
||||||
FreeFileNeeded();
|
FreeFileNeeded();
|
||||||
AllocFileNeeded(1);
|
AllocFileNeeded(1);
|
||||||
|
@ -275,9 +277,9 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
||||||
*/
|
*/
|
||||||
boolean CL_CheckDownloadable(void)
|
boolean CL_CheckDownloadable(void)
|
||||||
{
|
{
|
||||||
UINT8 i,dlstatus = 0;
|
UINT8 dlstatus = 0;
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (UINT8 i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
if (fileneeded[i].willsend == 1)
|
if (fileneeded[i].willsend == 1)
|
||||||
|
@ -298,7 +300,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
|
|
||||||
// not downloadable, put reason in console
|
// not downloadable, put reason in console
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (UINT8 i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||||
|
@ -368,14 +370,13 @@ void CL_AbortDownloadResume(void)
|
||||||
boolean CL_SendFileRequest(void)
|
boolean CL_SendFileRequest(void)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
INT32 i;
|
|
||||||
INT64 totalfreespaceneeded = 0, availablefreespace;
|
INT64 totalfreespaceneeded = 0, availablefreespace;
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
if (M_CheckParm("-nodownload"))
|
if (M_CheckParm("-nodownload"))
|
||||||
I_Error("Attempted to download files in -nodownload mode");
|
I_Error("Attempted to download files in -nodownload mode");
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (INT32 i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||||
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||||
{
|
{
|
||||||
|
@ -385,7 +386,7 @@ boolean CL_SendFileRequest(void)
|
||||||
|
|
||||||
netbuffer->packettype = PT_REQUESTFILE;
|
netbuffer->packettype = PT_REQUESTFILE;
|
||||||
p = (char *)netbuffer->u.textcmd;
|
p = (char *)netbuffer->u.textcmd;
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (INT32 i = 0; i < fileneedednum; i++)
|
||||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||||
{
|
{
|
||||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||||
|
@ -413,26 +414,31 @@ boolean CL_SendFileRequest(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get request filepak and put it on the send queue
|
// get request filepak and put it on the send queue
|
||||||
// returns false if a requested file was not found or cannot be sent
|
void PT_RequestFile(SINT8 node)
|
||||||
boolean PT_RequestFile(INT32 node)
|
|
||||||
{
|
{
|
||||||
UINT8 *p = netbuffer->u.textcmd;
|
UINT8 *p = netbuffer->u.textcmd;
|
||||||
UINT8 id;
|
|
||||||
|
if (client || !cv_downloading.value)
|
||||||
|
{
|
||||||
|
Net_CloseConnection(node); // close connection if you are not the server or disabled downloading
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow
|
while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow
|
||||||
{
|
{
|
||||||
id = READUINT8(p);
|
UINT8 id = READUINT8(p);
|
||||||
if (id == 0xFF)
|
if (id == 0xFF)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!AddFileToSendQueue(node, id))
|
if (!AddFileToSendQueue(node, id))
|
||||||
{
|
{
|
||||||
SV_AbortSendFiles(node);
|
SV_AbortSendFiles(node);
|
||||||
return false; // don't read the rest of the files
|
Net_CloseConnection(node); // close connection if one of the requested files could not be sent
|
||||||
|
return; // don't read the rest of the files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true; // no problems with any files
|
return; // no problems with any files
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the files needed aren't already loaded or on the disk
|
/** Checks if the files needed aren't already loaded or on the disk
|
||||||
|
@ -531,9 +537,7 @@ INT32 CL_CheckFiles(void)
|
||||||
// Load it now
|
// Load it now
|
||||||
boolean CL_LoadServerFiles(void)
|
boolean CL_LoadServerFiles(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
for (INT32 i = 0; i < fileneedednum; i++)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
|
||||||
{
|
{
|
||||||
if (fileneeded[i].status == FS_OPEN)
|
if (fileneeded[i].status == FS_OPEN)
|
||||||
continue; // Already loaded
|
continue; // Already loaded
|
||||||
|
@ -629,11 +633,10 @@ void AddLuaFileTransfer(const char *filename, const char *mode)
|
||||||
|
|
||||||
static void SV_PrepareSendLuaFileToNextNode(void)
|
static void SV_PrepareSendLuaFileToNextNode(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
UINT8 success = 1;
|
UINT8 success = 1;
|
||||||
|
|
||||||
// Find a client to send the file to
|
// Find a client to send the file to
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||||
if (luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting
|
if (luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting
|
||||||
{
|
{
|
||||||
// Tell the client we're about to send them the file
|
// Tell the client we're about to send them the file
|
||||||
|
@ -655,13 +658,12 @@ static void SV_PrepareSendLuaFileToNextNode(void)
|
||||||
void SV_PrepareSendLuaFile(void)
|
void SV_PrepareSendLuaFile(void)
|
||||||
{
|
{
|
||||||
char *binfilename;
|
char *binfilename;
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
luafiletransfers->ongoing = true;
|
luafiletransfers->ongoing = true;
|
||||||
|
|
||||||
// Set status to "waiting" for everyone
|
// Set status to "waiting" for everyone
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
luafiletransfers->nodestatus[i] = (nodeingame[i] ? LFTNS_WAITING : LFTNS_NONE);
|
luafiletransfers->nodestatus[i] = (netnodes[i].ingame ? LFTNS_WAITING : LFTNS_NONE);
|
||||||
|
|
||||||
if (FIL_ReadFileOK(luafiletransfers->realfilename))
|
if (FIL_ReadFileOK(luafiletransfers->realfilename))
|
||||||
{
|
{
|
||||||
|
@ -1137,12 +1139,13 @@ void FileSendTicker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PT_FileAck(void)
|
void PT_FileAck(SINT8 node)
|
||||||
{
|
{
|
||||||
fileack_pak *packet = &netbuffer->u.fileack;
|
fileack_pak *packet = &netbuffer->u.fileack;
|
||||||
INT32 node = doomcom->remotenode;
|
|
||||||
filetran_t *trans = &transfer[node];
|
filetran_t *trans = &transfer[node];
|
||||||
INT32 i, j;
|
|
||||||
|
if (client)
|
||||||
|
return;
|
||||||
|
|
||||||
// Wrong file id? Ignore it, it's probably a late packet
|
// Wrong file id? Ignore it, it's probably a late packet
|
||||||
if (!(trans->txlist && packet->fileid == trans->txlist->fileid))
|
if (!(trans->txlist && packet->fileid == trans->txlist->fileid))
|
||||||
|
@ -1161,11 +1164,11 @@ void PT_FileAck(void)
|
||||||
trans->dontsenduntil = 0;
|
trans->dontsenduntil = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < packet->numsegments; i++)
|
for (INT32 i = 0; i < packet->numsegments; i++)
|
||||||
{
|
{
|
||||||
fileacksegment_t *segment = &packet->segments[i];
|
fileacksegment_t *segment = &packet->segments[i];
|
||||||
|
|
||||||
for (j = 0; j < 32; j++)
|
for (INT32 j = 0; j < 32; j++)
|
||||||
if (LONG(segment->acks) & (1 << j))
|
if (LONG(segment->acks) & (1 << j))
|
||||||
{
|
{
|
||||||
if (LONG(segment->start) * FILEFRAGMENTSIZE >= trans->txlist->size)
|
if (LONG(segment->start) * FILEFRAGMENTSIZE >= trans->txlist->size)
|
||||||
|
@ -1190,24 +1193,23 @@ void PT_FileAck(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PT_FileReceived(void)
|
void PT_FileReceived(SINT8 node)
|
||||||
{
|
{
|
||||||
filetx_t *trans = transfer[doomcom->remotenode].txlist;
|
filetx_t *trans = transfer[node].txlist;
|
||||||
|
|
||||||
if (trans && netbuffer->u.filereceived == trans->fileid)
|
if (server && trans && netbuffer->u.filereceived == trans->fileid)
|
||||||
SV_EndFileSend(doomcom->remotenode);
|
SV_EndFileSend(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
|
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
|
||||||
{
|
{
|
||||||
size_t packetsize;
|
size_t packetsize;
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
packetsize = sizeof(*packet) + packet->numsegments * sizeof(*packet->segments);
|
packetsize = sizeof(*packet) + packet->numsegments * sizeof(*packet->segments);
|
||||||
|
|
||||||
// Finalise the packet
|
// Finalise the packet
|
||||||
packet->fileid = fileid;
|
packet->fileid = fileid;
|
||||||
for (i = 0; i < packet->numsegments; i++)
|
for (INT32 i = 0; i < packet->numsegments; i++)
|
||||||
{
|
{
|
||||||
packet->segments[i].start = LONG(packet->segments[i].start);
|
packet->segments[i].start = LONG(packet->segments[i].start);
|
||||||
packet->segments[i].acks = LONG(packet->segments[i].acks);
|
packet->segments[i].acks = LONG(packet->segments[i].acks);
|
||||||
|
@ -1247,9 +1249,7 @@ static void AddFragmentToAckPacket(fileack_pak *packet, UINT8 iteration, UINT32
|
||||||
|
|
||||||
void FileReceiveTicker(void)
|
void FileReceiveTicker(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
for (INT32 i = 0; i < fileneedednum; i++)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
|
||||||
{
|
{
|
||||||
fileneeded_t *file = &fileneeded[i];
|
fileneeded_t *file = &fileneeded[i];
|
||||||
|
|
||||||
|
@ -1263,8 +1263,7 @@ void FileReceiveTicker(void)
|
||||||
if (file->ackresendposition != UINT32_MAX && file->status == FS_DOWNLOADING)
|
if (file->ackresendposition != UINT32_MAX && file->status == FS_DOWNLOADING)
|
||||||
{
|
{
|
||||||
// Acknowledge ~70 MB/s, whichs means the client sends ~18 KB/s
|
// Acknowledge ~70 MB/s, whichs means the client sends ~18 KB/s
|
||||||
INT32 j;
|
for (INT32 j = 0; j < 2048; j++)
|
||||||
for (j = 0; j < 2048; j++)
|
|
||||||
{
|
{
|
||||||
if (file->receivedfragments[file->ackresendposition])
|
if (file->receivedfragments[file->ackresendposition])
|
||||||
AddFragmentToAckPacket(file->ackpacket, file->iteration, file->ackresendposition, i);
|
AddFragmentToAckPacket(file->ackpacket, file->iteration, file->ackresendposition, i);
|
||||||
|
@ -1281,8 +1280,27 @@ void FileReceiveTicker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PT_FileFragment(void)
|
void PT_FileFragment(SINT8 node, INT32 netconsole)
|
||||||
{
|
{
|
||||||
|
if (netnodes[node].ingame)
|
||||||
|
{
|
||||||
|
// Only accept PT_FILEFRAGMENT from the server.
|
||||||
|
if (node != servernode)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||||
|
if (server)
|
||||||
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (server)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (server || node != servernode)
|
||||||
|
{
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
||||||
fileneeded_t *file = &fileneeded[filenum];
|
fileneeded_t *file = &fileneeded[filenum];
|
||||||
UINT32 fragmentpos = LONG(netbuffer->u.filetxpak.position);
|
UINT32 fragmentpos = LONG(netbuffer->u.filetxpak.position);
|
||||||
|
@ -1439,9 +1457,7 @@ void PT_FileFragment(void)
|
||||||
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
|
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
lastfilenum = filenum;
|
lastfilenum = filenum;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Checks if a node is downloading a file
|
/** \brief Checks if a node is downloading a file
|
||||||
|
@ -1469,15 +1485,14 @@ void SV_AbortSendFiles(INT32 node)
|
||||||
|
|
||||||
void CloseNetFile(void)
|
void CloseNetFile(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
// Is sending?
|
// Is sending?
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
SV_AbortSendFiles(i);
|
SV_AbortSendFiles(i);
|
||||||
|
|
||||||
// Receiving a file?
|
// Receiving a file?
|
||||||
if (fileneeded)
|
if (fileneeded)
|
||||||
{
|
{
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (INT32 i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
|
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
|
||||||
{
|
{
|
||||||
fclose(fileneeded[i].file);
|
fclose(fileneeded[i].file);
|
||||||
|
@ -1510,9 +1525,7 @@ void CloseNetFile(void)
|
||||||
|
|
||||||
void Command_Downloads_f(void)
|
void Command_Downloads_f(void)
|
||||||
{
|
{
|
||||||
INT32 node;
|
for (INT32 node = 0; node < MAXNETNODES; node++)
|
||||||
|
|
||||||
for (node = 0; node < MAXNETNODES; node++)
|
|
||||||
if (transfer[node].txlist
|
if (transfer[node].txlist
|
||||||
&& transfer[node].txlist->ram == SF_FILE) // Node is downloading a file?
|
&& transfer[node].txlist->ram == SF_FILE) // Node is downloading a file?
|
||||||
{
|
{
|
||||||
|
@ -1546,14 +1559,11 @@ void Command_Downloads_f(void)
|
||||||
|
|
||||||
void nameonly(char *s)
|
void nameonly(char *s)
|
||||||
{
|
{
|
||||||
size_t j, len;
|
for (size_t j = strlen(s); j != (size_t)-1; j--)
|
||||||
void *ns;
|
|
||||||
|
|
||||||
for (j = strlen(s); j != (size_t)-1; j--)
|
|
||||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||||
{
|
{
|
||||||
ns = &(s[j+1]);
|
void *ns = &(s[j+1]);
|
||||||
len = strlen(ns);
|
size_t len = strlen(ns);
|
||||||
#if 0
|
#if 0
|
||||||
M_Memcpy(s, ns, len+1);
|
M_Memcpy(s, ns, len+1);
|
||||||
#else
|
#else
|
||||||
|
@ -1566,9 +1576,9 @@ void nameonly(char *s)
|
||||||
// Returns the length in characters of the last element of a path.
|
// Returns the length in characters of the last element of a path.
|
||||||
size_t nameonlylength(const char *s)
|
size_t nameonlylength(const char *s)
|
||||||
{
|
{
|
||||||
size_t j, len = strlen(s);
|
size_t len = strlen(s);
|
||||||
|
|
||||||
for (j = len; j != (size_t)-1; j--)
|
for (size_t j = len; j != (size_t)-1; j--)
|
||||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||||
return len - j - 1;
|
return len - j - 1;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
#include "w_wad.h"
|
#include "../w_wad.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -70,13 +70,13 @@ extern INT32 fileneedednum;
|
||||||
extern fileneeded_t *fileneeded;
|
extern fileneeded_t *fileneeded;
|
||||||
extern char downloaddir[512];
|
extern char downloaddir[512];
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
extern INT32 lastfilenum;
|
extern INT32 lastfilenum;
|
||||||
extern INT32 downloadcompletednum;
|
extern INT32 downloadcompletednum;
|
||||||
extern UINT32 downloadcompletedsize;
|
extern UINT32 downloadcompletedsize;
|
||||||
extern INT32 totalfilesrequestednum;
|
extern INT32 totalfilesrequestednum;
|
||||||
extern UINT32 totalfilesrequestedsize;
|
extern UINT32 totalfilesrequestedsize;
|
||||||
#endif
|
|
||||||
|
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||||
|
|
||||||
void AllocFileNeeded(INT32 size);
|
void AllocFileNeeded(INT32 size);
|
||||||
void FreeFileNeeded(void);
|
void FreeFileNeeded(void);
|
||||||
|
@ -90,16 +90,16 @@ void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemet
|
||||||
UINT8 fileid);
|
UINT8 fileid);
|
||||||
|
|
||||||
void FileSendTicker(void);
|
void FileSendTicker(void);
|
||||||
void PT_FileAck(void);
|
void PT_FileAck(SINT8 node);
|
||||||
void PT_FileReceived(void);
|
void PT_FileReceived(SINT8 node);
|
||||||
boolean SendingFile(INT32 node);
|
boolean SendingFile(INT32 node);
|
||||||
|
|
||||||
void FileReceiveTicker(void);
|
void FileReceiveTicker(void);
|
||||||
void PT_FileFragment(void);
|
void PT_FileFragment(SINT8 node, INT32 netconsole);
|
||||||
|
|
||||||
boolean CL_CheckDownloadable(void);
|
boolean CL_CheckDownloadable(void);
|
||||||
boolean CL_SendFileRequest(void);
|
boolean CL_SendFileRequest(void);
|
||||||
boolean PT_RequestFile(INT32 node);
|
void PT_RequestFile(SINT8 node);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
336
src/netcode/gamestate.c
Normal file
336
src/netcode/gamestate.c
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file gamestate.c
|
||||||
|
/// \brief Gamestate (re)sending
|
||||||
|
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "d_netfil.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "server_connection.h"
|
||||||
|
#include "../am_map.h"
|
||||||
|
#include "../byteptr.h"
|
||||||
|
#include "../console.h"
|
||||||
|
#include "../d_main.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
#include "../f_finale.h"
|
||||||
|
#include "../g_demo.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../i_time.h"
|
||||||
|
#include "../lua_script.h"
|
||||||
|
#include "../lzf.h"
|
||||||
|
#include "../m_misc.h"
|
||||||
|
#include "../p_local.h"
|
||||||
|
#include "../p_saveg.h"
|
||||||
|
#include "../r_main.h"
|
||||||
|
#include "../tables.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#if defined (__GNUC__) || defined (__unix__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SAVEGAMESIZE (768*1024)
|
||||||
|
|
||||||
|
UINT8 hu_redownloadinggamestate = 0;
|
||||||
|
boolean cl_redownloadinggamestate = false;
|
||||||
|
|
||||||
|
boolean SV_ResendingSavegameToAnyone(void)
|
||||||
|
{
|
||||||
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
|
if (netnodes[i].resendingsavegame)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SV_SendSaveGame(INT32 node, boolean resending)
|
||||||
|
{
|
||||||
|
size_t length, compressedlen;
|
||||||
|
UINT8 *savebuffer;
|
||||||
|
UINT8 *compressedsave;
|
||||||
|
UINT8 *buffertosend;
|
||||||
|
|
||||||
|
// first save it in a malloced buffer
|
||||||
|
savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||||
|
if (!savebuffer)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leave room for the uncompressed length.
|
||||||
|
save_p = savebuffer + sizeof(UINT32);
|
||||||
|
|
||||||
|
P_SaveNetGame(resending);
|
||||||
|
|
||||||
|
length = save_p - savebuffer;
|
||||||
|
if (length > SAVEGAMESIZE)
|
||||||
|
{
|
||||||
|
free(savebuffer);
|
||||||
|
save_p = NULL;
|
||||||
|
I_Error("Savegame buffer overrun");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for compressed save: one byte fewer than for the
|
||||||
|
// uncompressed data to ensure that the compression is worthwhile.
|
||||||
|
compressedsave = malloc(length - 1);
|
||||||
|
if (!compressedsave)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to compress it.
|
||||||
|
if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||||
|
{
|
||||||
|
// Compressing succeeded; send compressed data
|
||||||
|
|
||||||
|
free(savebuffer);
|
||||||
|
|
||||||
|
// State that we're compressed.
|
||||||
|
buffertosend = compressedsave;
|
||||||
|
WRITEUINT32(compressedsave, length - sizeof(UINT32));
|
||||||
|
length = compressedlen + sizeof(UINT32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Compression failed to make it smaller; send original
|
||||||
|
|
||||||
|
free(compressedsave);
|
||||||
|
|
||||||
|
// State that we're not compressed
|
||||||
|
buffertosend = savebuffer;
|
||||||
|
WRITEUINT32(savebuffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0);
|
||||||
|
save_p = NULL;
|
||||||
|
|
||||||
|
// Remember when we started sending the savegame so we can handle timeouts
|
||||||
|
netnodes[node].sendingsavegame = true;
|
||||||
|
netnodes[node].freezetimeout = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DUMPCONSISTENCY
|
||||||
|
#define TMPSAVENAME "badmath.sav"
|
||||||
|
static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
void SV_SavedGame(void)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
UINT8 *savebuffer;
|
||||||
|
char tmpsave[256];
|
||||||
|
|
||||||
|
if (!cv_dumpconsistency.value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||||
|
|
||||||
|
// first save it in a malloced buffer
|
||||||
|
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||||
|
if (!save_p)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
P_SaveNetGame(false);
|
||||||
|
|
||||||
|
length = save_p - savebuffer;
|
||||||
|
if (length > SAVEGAMESIZE)
|
||||||
|
{
|
||||||
|
free(savebuffer);
|
||||||
|
save_p = NULL;
|
||||||
|
I_Error("Savegame buffer overrun");
|
||||||
|
}
|
||||||
|
|
||||||
|
// then save it!
|
||||||
|
if (!FIL_WriteFile(tmpsave, savebuffer, length))
|
||||||
|
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
|
||||||
|
|
||||||
|
free(savebuffer);
|
||||||
|
save_p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TMPSAVENAME
|
||||||
|
#endif
|
||||||
|
#define TMPSAVENAME "$$$.sav"
|
||||||
|
|
||||||
|
|
||||||
|
void CL_LoadReceivedSavegame(boolean reloading)
|
||||||
|
{
|
||||||
|
UINT8 *savebuffer = NULL;
|
||||||
|
size_t length, decompressedlen;
|
||||||
|
char tmpsave[256];
|
||||||
|
|
||||||
|
FreeFileNeeded();
|
||||||
|
|
||||||
|
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||||
|
|
||||||
|
length = FIL_ReadFile(tmpsave, &savebuffer);
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
|
||||||
|
if (!length)
|
||||||
|
{
|
||||||
|
I_Error("Can't read savegame sent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
save_p = savebuffer;
|
||||||
|
|
||||||
|
// Decompress saved game if necessary.
|
||||||
|
decompressedlen = READUINT32(save_p);
|
||||||
|
if(decompressedlen > 0)
|
||||||
|
{
|
||||||
|
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
|
||||||
|
lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||||
|
Z_Free(savebuffer);
|
||||||
|
save_p = savebuffer = decompressedbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
paused = false;
|
||||||
|
demoplayback = false;
|
||||||
|
titlemapinaction = TITLEMAP_OFF;
|
||||||
|
titledemo = false;
|
||||||
|
automapactive = false;
|
||||||
|
|
||||||
|
// load a base level
|
||||||
|
if (P_LoadNetGame(reloading))
|
||||||
|
{
|
||||||
|
const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||||
|
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
|
||||||
|
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
|
||||||
|
{
|
||||||
|
CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl);
|
||||||
|
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||||
|
CONS_Printf(M_GetText(" Zone"));
|
||||||
|
if (actnum > 0)
|
||||||
|
CONS_Printf(" %2d", actnum);
|
||||||
|
}
|
||||||
|
CONS_Printf("\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
Z_Free(savebuffer);
|
||||||
|
save_p = NULL;
|
||||||
|
if (unlink(tmpsave) == -1)
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||||
|
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||||
|
CON_ToggleOff();
|
||||||
|
|
||||||
|
// Tell the server we have received and reloaded the gamestate
|
||||||
|
// so they know they can resume the game
|
||||||
|
netbuffer->packettype = PT_RECEIVEDGAMESTATE;
|
||||||
|
HSendPacket(servernode, true, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_ReloadReceivedSavegame(void)
|
||||||
|
{
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
LUA_InvalidatePlayer(&players[i]);
|
||||||
|
sprintf(player_names[i], "Player %d", i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CL_LoadReceivedSavegame(true);
|
||||||
|
|
||||||
|
neededtic = max(neededtic, gametic);
|
||||||
|
maketic = neededtic;
|
||||||
|
|
||||||
|
ticcmd_oldangleturn[0] = players[consoleplayer].oldrelangleturn;
|
||||||
|
P_ForceLocalAngle(&players[consoleplayer], (angle_t)(players[consoleplayer].angleturn << 16));
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
ticcmd_oldangleturn[1] = players[secondarydisplayplayer].oldrelangleturn;
|
||||||
|
P_ForceLocalAngle(&players[secondarydisplayplayer], (angle_t)(players[secondarydisplayplayer].angleturn << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.subsector = R_PointInSubsector(camera.x, camera.y);
|
||||||
|
camera2.subsector = R_PointInSubsector(camera2.x, camera2.y);
|
||||||
|
|
||||||
|
cl_redownloadinggamestate = false;
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText("Game state reloaded\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_ResendGamestate(void)
|
||||||
|
{
|
||||||
|
SINT8 playernum;
|
||||||
|
|
||||||
|
if (COM_Argc() == 1)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("resendgamestate <playername/playernum>: resend the game state to a player\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (client)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playernum = nametonum(COM_Argv(1));
|
||||||
|
if (playernum == -1 || playernum == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on
|
||||||
|
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||||
|
if (!HSendPacket(playernode[playernum], true, 0, 0))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("A problem occurred, please try again.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_CanReceiveGamestate(SINT8 node)
|
||||||
|
{
|
||||||
|
if (client || netnodes[node].sendingsavegame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[netnodes[node].player]);
|
||||||
|
|
||||||
|
SV_SendSaveGame(node, true); // Resend a complete game state
|
||||||
|
netnodes[node].resendingsavegame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_ReceivedGamestate(SINT8 node)
|
||||||
|
{
|
||||||
|
netnodes[node].sendingsavegame = false;
|
||||||
|
netnodes[node].resendingsavegame = false;
|
||||||
|
netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_WillResendGamestate(SINT8 node)
|
||||||
|
{
|
||||||
|
(void)node;
|
||||||
|
|
||||||
|
char tmpsave[256];
|
||||||
|
|
||||||
|
if (server || cl_redownloadinggamestate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Send back a PT_CANRECEIVEGAMESTATE packet to the server
|
||||||
|
// so they know they can start sending the game state
|
||||||
|
netbuffer->packettype = PT_CANRECEIVEGAMESTATE;
|
||||||
|
if (!HSendPacket(servernode, true, 0, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText("Reloading game state...\n"));
|
||||||
|
|
||||||
|
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||||
|
|
||||||
|
// Don't get a corrupt savegame error because tmpsave already exists
|
||||||
|
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
|
||||||
|
I_Error("Can't delete %s\n", tmpsave);
|
||||||
|
|
||||||
|
CL_PrepareDownloadSaveGame(tmpsave);
|
||||||
|
|
||||||
|
cl_redownloadinggamestate = true;
|
||||||
|
}
|
31
src/netcode/gamestate.h
Normal file
31
src/netcode/gamestate.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file gamestate.h
|
||||||
|
/// \brief Gamestate (re)sending
|
||||||
|
|
||||||
|
#ifndef __GAMESTATE__
|
||||||
|
#define __GAMESTATE__
|
||||||
|
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
extern UINT8 hu_redownloadinggamestate;
|
||||||
|
extern boolean cl_redownloadinggamestate;
|
||||||
|
|
||||||
|
boolean SV_ResendingSavegameToAnyone(void);
|
||||||
|
void SV_SendSaveGame(INT32 node, boolean resending);
|
||||||
|
void SV_SavedGame(void);
|
||||||
|
void CL_LoadReceivedSavegame(boolean reloading);
|
||||||
|
void CL_ReloadReceivedSavegame(void);
|
||||||
|
void Command_ResendGamestate(void);
|
||||||
|
void PT_CanReceiveGamestate(SINT8 node);
|
||||||
|
void PT_ReceivedGamestate(SINT8 node);
|
||||||
|
void PT_WillResendGamestate(SINT8 node);
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,14 +18,15 @@ Documentation available here.
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
#include "command.h"
|
#include "client_connection.h"
|
||||||
#include "m_argv.h"
|
#include "../command.h"
|
||||||
#include "m_menu.h"
|
#include "../m_argv.h"
|
||||||
|
#include "../m_menu.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "i_tcp.h"/* for current_port */
|
#include "i_tcp.h"/* for current_port */
|
||||||
#include "i_threads.h"
|
#include "../i_threads.h"
|
||||||
|
|
||||||
/* reasonable default I guess?? */
|
/* reasonable default I guess?? */
|
||||||
#define DEFAULT_BUFFER_SIZE (4096)
|
#define DEFAULT_BUFFER_SIZE (4096)
|
||||||
|
@ -95,7 +96,7 @@ init_user_agent_once(void)
|
||||||
{
|
{
|
||||||
if (hms_useragent[0] != '\0')
|
if (hms_useragent[0] != '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
get_user_agent(hms_useragent, 512);
|
get_user_agent(hms_useragent, 512);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "command.h"
|
#include "../command.h"
|
||||||
|
|
||||||
/// \brief program net id
|
/// \brief program net id
|
||||||
#define DOOMCOM_ID (INT32)0x12345678l
|
#define DOOMCOM_ID (INT32)0x12345678l
|
|
@ -36,109 +36,100 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
|
|
||||||
#if defined (NOMD5) && !defined (NONET)
|
#ifdef USE_WINSOCK1
|
||||||
//#define NONET
|
#include <winsock.h>
|
||||||
|
#else
|
||||||
|
#ifndef USE_WINSOCK
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#ifdef __APPLE_CC__
|
||||||
|
#ifndef _BSD_SOCKLEN_T_
|
||||||
|
#define _BSD_SOCKLEN_T_
|
||||||
|
#endif //_BSD_SOCKLEN_T_
|
||||||
|
#endif //__APPLE_CC__
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif //normal BSD API
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif // UNIXCOMMON
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NONET
|
#ifdef USE_WINSOCK
|
||||||
#undef HAVE_MINIUPNPC
|
// some undefined under win32
|
||||||
#else
|
#undef errno
|
||||||
#ifdef USE_WINSOCK1
|
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right?
|
||||||
#include <winsock.h>
|
#define errno h_errno // some very strange things happen when not using h_error?!?
|
||||||
#else
|
#ifdef EWOULDBLOCK
|
||||||
#ifndef USE_WINSOCK
|
#undef EWOULDBLOCK
|
||||||
#include <arpa/inet.h>
|
|
||||||
#ifdef __APPLE_CC__
|
|
||||||
#ifndef _BSD_SOCKLEN_T_
|
|
||||||
#define _BSD_SOCKLEN_T_
|
|
||||||
#endif //_BSD_SOCKLEN_T_
|
|
||||||
#endif //__APPLE_CC__
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#endif //normal BSD API
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif // UNIXCOMMON
|
|
||||||
#endif
|
#endif
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
#ifdef USE_WINSOCK
|
#ifdef EMSGSIZE
|
||||||
// some undefined under win32
|
#undef EMSGSIZE
|
||||||
#undef errno
|
|
||||||
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right?
|
|
||||||
#define errno h_errno // some very strange things happen when not using h_error?!?
|
|
||||||
#ifdef EWOULDBLOCK
|
|
||||||
#undef EWOULDBLOCK
|
|
||||||
#endif
|
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
|
||||||
#ifdef EMSGSIZE
|
|
||||||
#undef EMSGSIZE
|
|
||||||
#endif
|
|
||||||
#define EMSGSIZE WSAEMSGSIZE
|
|
||||||
#ifdef ECONNREFUSED
|
|
||||||
#undef ECONNREFUSED
|
|
||||||
#endif
|
|
||||||
#define ECONNREFUSED WSAECONNREFUSED
|
|
||||||
#ifdef ETIMEDOUT
|
|
||||||
#undef ETIMEDOUT
|
|
||||||
#endif
|
|
||||||
#define ETIMEDOUT WSAETIMEDOUT
|
|
||||||
#ifndef IOC_VENDOR
|
|
||||||
#define IOC_VENDOR 0x18000000
|
|
||||||
#endif
|
|
||||||
#ifndef _WSAIOW
|
|
||||||
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
|
||||||
#endif
|
|
||||||
#ifndef SIO_UDP_CONNRESET
|
|
||||||
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
|
||||||
#endif
|
|
||||||
#ifndef AI_ADDRCONFIG
|
|
||||||
#define AI_ADDRCONFIG 0x00000400
|
|
||||||
#endif
|
|
||||||
#ifndef STATUS_INVALID_PARAMETER
|
|
||||||
#define STATUS_INVALID_PARAMETER 0xC000000D
|
|
||||||
#endif
|
|
||||||
#endif // USE_WINSOCK
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
struct sockaddr any;
|
|
||||||
struct sockaddr_in ip4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
struct sockaddr_in6 ip6;
|
|
||||||
#endif
|
#endif
|
||||||
} mysockaddr_t;
|
#define EMSGSIZE WSAEMSGSIZE
|
||||||
|
#ifdef ECONNREFUSED
|
||||||
|
#undef ECONNREFUSED
|
||||||
|
#endif
|
||||||
|
#define ECONNREFUSED WSAECONNREFUSED
|
||||||
|
#ifdef ETIMEDOUT
|
||||||
|
#undef ETIMEDOUT
|
||||||
|
#endif
|
||||||
|
#define ETIMEDOUT WSAETIMEDOUT
|
||||||
|
#ifndef IOC_VENDOR
|
||||||
|
#define IOC_VENDOR 0x18000000
|
||||||
|
#endif
|
||||||
|
#ifndef _WSAIOW
|
||||||
|
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
||||||
|
#endif
|
||||||
|
#ifndef SIO_UDP_CONNRESET
|
||||||
|
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||||
|
#endif
|
||||||
|
#ifndef AI_ADDRCONFIG
|
||||||
|
#define AI_ADDRCONFIG 0x00000400
|
||||||
|
#endif
|
||||||
|
#ifndef STATUS_INVALID_PARAMETER
|
||||||
|
#define STATUS_INVALID_PARAMETER 0xC000000D
|
||||||
|
#endif
|
||||||
|
#endif // USE_WINSOCK
|
||||||
|
|
||||||
#ifdef HAVE_MINIUPNPC
|
typedef union
|
||||||
#ifdef STATIC_MINIUPNPC
|
{
|
||||||
#define STATICLIB
|
struct sockaddr any;
|
||||||
#endif
|
struct sockaddr_in ip4;
|
||||||
#include "miniupnpc/miniwget.h"
|
#ifdef HAVE_IPV6
|
||||||
#include "miniupnpc/miniupnpc.h"
|
struct sockaddr_in6 ip6;
|
||||||
#include "miniupnpc/upnpcommands.h"
|
#endif
|
||||||
#undef STATICLIB
|
} mysockaddr_t;
|
||||||
static UINT8 UPNP_support = TRUE;
|
|
||||||
#endif // HAVE_MINIUPNC
|
|
||||||
|
|
||||||
#endif // !NONET
|
#ifdef HAVE_MINIUPNPC
|
||||||
|
#ifdef STATIC_MINIUPNPC
|
||||||
|
#define STATICLIB
|
||||||
|
#endif
|
||||||
|
#include "miniupnpc/miniwget.h"
|
||||||
|
#include "miniupnpc/miniupnpc.h"
|
||||||
|
#include "miniupnpc/upnpcommands.h"
|
||||||
|
#undef STATICLIB
|
||||||
|
static UINT8 UPNP_support = TRUE;
|
||||||
|
#endif // HAVE_MINIUPNC
|
||||||
|
|
||||||
#define MAXBANS 100
|
#define MAXBANS 100
|
||||||
|
|
||||||
#include "i_system.h"
|
#include "../i_system.h"
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "i_tcp.h"
|
#include "i_tcp.h"
|
||||||
#include "m_argv.h"
|
#include "../m_argv.h"
|
||||||
|
|
||||||
#include "doomstat.h"
|
#include "../doomstat.h"
|
||||||
|
|
||||||
// win32
|
// win32
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
|
@ -151,7 +142,7 @@
|
||||||
#define SELECTTEST
|
#define SELECTTEST
|
||||||
#define DEFAULTPORT "5029"
|
#define DEFAULTPORT "5029"
|
||||||
|
|
||||||
#if defined (USE_WINSOCK) && !defined (NONET)
|
#ifdef USE_WINSOCK
|
||||||
typedef SOCKET SOCKET_TYPE;
|
typedef SOCKET SOCKET_TYPE;
|
||||||
#define ERRSOCKET (SOCKET_ERROR)
|
#define ERRSOCKET (SOCKET_ERROR)
|
||||||
#else
|
#else
|
||||||
|
@ -163,22 +154,20 @@
|
||||||
#define ERRSOCKET (-1)
|
#define ERRSOCKET (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
// define socklen_t in DOS/Windows if it is not already defined
|
||||||
// define socklen_t in DOS/Windows if it is not already defined
|
#ifdef USE_WINSOCK1
|
||||||
#ifdef USE_WINSOCK1
|
typedef int socklen_t;
|
||||||
typedef int socklen_t;
|
|
||||||
#endif
|
|
||||||
static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET};
|
|
||||||
static size_t mysocketses = 0;
|
|
||||||
static int myfamily[MAXNETNODES+1] = {0};
|
|
||||||
static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET};
|
|
||||||
static mysockaddr_t clientaddress[MAXNETNODES+1];
|
|
||||||
static mysockaddr_t broadcastaddress[MAXNETNODES+1];
|
|
||||||
static size_t broadcastaddresses = 0;
|
|
||||||
static boolean nodeconnected[MAXNETNODES+1];
|
|
||||||
static mysockaddr_t banned[MAXBANS];
|
|
||||||
static UINT8 bannedmask[MAXBANS];
|
|
||||||
#endif
|
#endif
|
||||||
|
static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET};
|
||||||
|
static size_t mysocketses = 0;
|
||||||
|
static int myfamily[MAXNETNODES+1] = {0};
|
||||||
|
static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET};
|
||||||
|
static mysockaddr_t clientaddress[MAXNETNODES+1];
|
||||||
|
static mysockaddr_t broadcastaddress[MAXNETNODES+1];
|
||||||
|
static size_t broadcastaddresses = 0;
|
||||||
|
static boolean nodeconnected[MAXNETNODES+1];
|
||||||
|
static mysockaddr_t banned[MAXBANS];
|
||||||
|
static UINT8 bannedmask[MAXBANS];
|
||||||
|
|
||||||
static size_t numbans = 0;
|
static size_t numbans = 0;
|
||||||
static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1?
|
static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1?
|
||||||
|
@ -187,7 +176,6 @@ static boolean init_tcp_driver = false;
|
||||||
static const char *serverport_name = DEFAULTPORT;
|
static const char *serverport_name = DEFAULTPORT;
|
||||||
static const char *clientport_name;/* any port */
|
static const char *clientport_name;/* any port */
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
// stupid microsoft makes things complicated
|
// stupid microsoft makes things complicated
|
||||||
static char *get_WSAErrorStr(int e)
|
static char *get_WSAErrorStr(int e)
|
||||||
|
@ -387,47 +375,33 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||||
#endif
|
#endif
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *SOCK_GetNodeAddress(INT32 node)
|
static const char *SOCK_GetNodeAddress(INT32 node)
|
||||||
{
|
{
|
||||||
if (node == 0)
|
if (node == 0)
|
||||||
return "self";
|
return "self";
|
||||||
#ifdef NONET
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
if (!nodeconnected[node])
|
if (!nodeconnected[node])
|
||||||
return NULL;
|
return NULL;
|
||||||
return SOCK_AddrToStr(&clientaddress[node]);
|
return SOCK_AddrToStr(&clientaddress[node]);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *SOCK_GetBanAddress(size_t ban)
|
static const char *SOCK_GetBanAddress(size_t ban)
|
||||||
{
|
{
|
||||||
if (ban >= numbans)
|
if (ban >= numbans)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef NONET
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
return SOCK_AddrToStr(&banned[ban]);
|
return SOCK_AddrToStr(&banned[ban]);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *SOCK_GetBanMask(size_t ban)
|
static const char *SOCK_GetBanMask(size_t ban)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)ban;
|
|
||||||
#else
|
|
||||||
static char s[16]; //255.255.255.255 netmask? no, just CDIR for only
|
static char s[16]; //255.255.255.255 netmask? no, just CDIR for only
|
||||||
if (ban >= numbans)
|
if (ban >= numbans)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (sprintf(s,"%d",bannedmask[ban]) > 0)
|
if (sprintf(s,"%d",bannedmask[ban]) > 0)
|
||||||
return s;
|
return s;
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||||
{
|
{
|
||||||
UINT32 bitmask = INADDR_NONE;
|
UINT32 bitmask = INADDR_NONE;
|
||||||
|
@ -455,24 +429,20 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||||
*/
|
*/
|
||||||
static void cleanupnodes(void)
|
static void cleanupnodes(void)
|
||||||
{
|
{
|
||||||
SINT8 j;
|
|
||||||
|
|
||||||
if (!Playing())
|
if (!Playing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Why can't I start at zero?
|
// Why can't I start at zero?
|
||||||
for (j = 1; j < MAXNETNODES; j++)
|
for (SINT8 j = 1; j < MAXNETNODES; j++)
|
||||||
if (!(nodeingame[j] || SendingFile(j)))
|
if (!(netnodes[j].ingame || SendingFile(j)))
|
||||||
nodeconnected[j] = false;
|
nodeconnected[j] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SINT8 getfreenode(void)
|
static SINT8 getfreenode(void)
|
||||||
{
|
{
|
||||||
SINT8 j;
|
|
||||||
|
|
||||||
cleanupnodes();
|
cleanupnodes();
|
||||||
|
|
||||||
for (j = 0; j < MAXNETNODES; j++)
|
for (SINT8 j = 0; j < MAXNETNODES; j++)
|
||||||
if (!nodeconnected[j])
|
if (!nodeconnected[j])
|
||||||
{
|
{
|
||||||
nodeconnected[j] = true;
|
nodeconnected[j] = true;
|
||||||
|
@ -485,8 +455,8 @@ static SINT8 getfreenode(void)
|
||||||
* downloading a needed wad, but it's better than not letting anyone join...
|
* downloading a needed wad, but it's better than not letting anyone join...
|
||||||
*/
|
*/
|
||||||
/*I_Error("No more free nodes!!1!11!11!!1111\n");
|
/*I_Error("No more free nodes!!1!11!11!!1111\n");
|
||||||
for (j = 1; j < MAXNETNODES; j++)
|
for (SINT8 j = 1; j < MAXNETNODES; j++)
|
||||||
if (!nodeingame[j])
|
if (!netnodes[j].ingame)
|
||||||
return j;*/
|
return j;*/
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -497,28 +467,27 @@ void Command_Numnodes(void)
|
||||||
{
|
{
|
||||||
INT32 connected = 0;
|
INT32 connected = 0;
|
||||||
INT32 ingame = 0;
|
INT32 ingame = 0;
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||||
{
|
{
|
||||||
if (!(nodeconnected[i] || nodeingame[i]))
|
if (!(nodeconnected[i] || netnodes[i].ingame))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nodeconnected[i])
|
if (nodeconnected[i])
|
||||||
connected++;
|
connected++;
|
||||||
if (nodeingame[i])
|
if (netnodes[i].ingame)
|
||||||
ingame++;
|
ingame++;
|
||||||
|
|
||||||
CONS_Printf("%2d - ", i);
|
CONS_Printf("%2d - ", i);
|
||||||
if (nodetoplayer[i] != -1)
|
if (netnodes[i].player != -1)
|
||||||
CONS_Printf("player %.2d", nodetoplayer[i]);
|
CONS_Printf("player %.2d", netnodes[i].player);
|
||||||
else
|
else
|
||||||
CONS_Printf(" ");
|
CONS_Printf(" ");
|
||||||
if (nodeconnected[i])
|
if (nodeconnected[i])
|
||||||
CONS_Printf(" - connected");
|
CONS_Printf(" - connected");
|
||||||
else
|
else
|
||||||
CONS_Printf(" - ");
|
CONS_Printf(" - ");
|
||||||
if (nodeingame[i])
|
if (netnodes[i].ingame)
|
||||||
CONS_Printf(" - ingame");
|
CONS_Printf(" - ingame");
|
||||||
else
|
else
|
||||||
CONS_Printf(" - ");
|
CONS_Printf(" - ");
|
||||||
|
@ -531,19 +500,17 @@ void Command_Numnodes(void)
|
||||||
connected, ingame);
|
connected, ingame);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// Returns true if a packet was received from a new node, false in all other cases
|
// Returns true if a packet was received from a new node, false in all other cases
|
||||||
static boolean SOCK_Get(void)
|
static boolean SOCK_Get(void)
|
||||||
{
|
{
|
||||||
size_t i, n;
|
size_t i;
|
||||||
int j;
|
int j;
|
||||||
ssize_t c;
|
ssize_t c;
|
||||||
mysockaddr_t fromaddress;
|
mysockaddr_t fromaddress;
|
||||||
socklen_t fromlen;
|
socklen_t fromlen;
|
||||||
|
|
||||||
for (n = 0; n < mysocketses; n++)
|
for (size_t n = 0; n < mysocketses; n++)
|
||||||
{
|
{
|
||||||
fromlen = (socklen_t)sizeof(fromaddress);
|
fromlen = (socklen_t)sizeof(fromaddress);
|
||||||
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
|
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
|
||||||
|
@ -596,20 +563,17 @@ static boolean SOCK_Get(void)
|
||||||
doomcom->remotenode = -1; // no packet
|
doomcom->remotenode = -1; // no packet
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// check if we can send (do not go over the buffer)
|
// check if we can send (do not go over the buffer)
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
static fd_set masterset;
|
static fd_set masterset;
|
||||||
|
|
||||||
#ifdef SELECTTEST
|
#ifdef SELECTTEST
|
||||||
static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len)
|
static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
boolean testset = false;
|
boolean testset = false;
|
||||||
FD_ZERO(dst);
|
FD_ZERO(dst);
|
||||||
for (i = 0; i < len;i++)
|
for (size_t i = 0; i < len;i++)
|
||||||
{
|
{
|
||||||
if(fd[i] != (SOCKET_TYPE)ERRSOCKET &&
|
if(fd[i] != (SOCKET_TYPE)ERRSOCKET &&
|
||||||
FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups
|
FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups
|
||||||
|
@ -649,9 +613,7 @@ static boolean SOCK_CanGet(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
|
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
|
||||||
{
|
{
|
||||||
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
|
@ -675,16 +637,15 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
||||||
static void SOCK_Send(void)
|
static void SOCK_Send(void)
|
||||||
{
|
{
|
||||||
ssize_t c = ERRSOCKET;
|
ssize_t c = ERRSOCKET;
|
||||||
size_t i, j;
|
|
||||||
|
|
||||||
if (!nodeconnected[doomcom->remotenode])
|
if (!nodeconnected[doomcom->remotenode])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (doomcom->remotenode == BROADCASTADDR)
|
if (doomcom->remotenode == BROADCASTADDR)
|
||||||
{
|
{
|
||||||
for (i = 0; i < mysocketses; i++)
|
for (size_t i = 0; i < mysocketses; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < broadcastaddresses; j++)
|
for (size_t j = 0; j < broadcastaddresses; j++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||||
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||||
|
@ -694,7 +655,7 @@ static void SOCK_Send(void)
|
||||||
}
|
}
|
||||||
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
|
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
|
||||||
{
|
{
|
||||||
for (i = 0; i < mysocketses; i++)
|
for (size_t i = 0; i < mysocketses; i++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||||
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||||
|
@ -714,9 +675,7 @@ static void SOCK_Send(void)
|
||||||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void SOCK_FreeNodenum(INT32 numnode)
|
static void SOCK_FreeNodenum(INT32 numnode)
|
||||||
{
|
{
|
||||||
// can't disconnect from self :)
|
// can't disconnect from self :)
|
||||||
|
@ -731,12 +690,10 @@ static void SOCK_FreeNodenum(INT32 numnode)
|
||||||
// put invalid address
|
// put invalid address
|
||||||
memset(&clientaddress[numnode], 0, sizeof (clientaddress[numnode]));
|
memset(&clientaddress[numnode], 0, sizeof (clientaddress[numnode]));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// UDPsocket
|
// UDPsocket
|
||||||
//
|
//
|
||||||
#ifndef NONET
|
|
||||||
|
|
||||||
// allocate a socket
|
// allocate a socket
|
||||||
static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen)
|
static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen)
|
||||||
|
@ -1061,12 +1018,10 @@ static boolean UDP_Socket(void)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
boolean I_InitTcpDriver(void)
|
boolean I_InitTcpDriver(void)
|
||||||
{
|
{
|
||||||
boolean tcp_was_up = init_tcp_driver;
|
boolean tcp_was_up = init_tcp_driver;
|
||||||
#ifndef NONET
|
|
||||||
if (!init_tcp_driver)
|
if (!init_tcp_driver)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
|
@ -1121,7 +1076,7 @@ boolean I_InitTcpDriver(void)
|
||||||
#endif
|
#endif
|
||||||
init_tcp_driver = true;
|
init_tcp_driver = true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (!tcp_was_up && init_tcp_driver)
|
if (!tcp_was_up && init_tcp_driver)
|
||||||
{
|
{
|
||||||
I_AddExitFunc(I_ShutdownTcpDriver);
|
I_AddExitFunc(I_ShutdownTcpDriver);
|
||||||
|
@ -1135,11 +1090,9 @@ boolean I_InitTcpDriver(void)
|
||||||
return init_tcp_driver;
|
return init_tcp_driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void SOCK_CloseSocket(void)
|
static void SOCK_CloseSocket(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
for (size_t i=0; i < MAXNETNODES+1; i++)
|
||||||
for (i=0; i < MAXNETNODES+1; i++)
|
|
||||||
{
|
{
|
||||||
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET
|
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET
|
||||||
&& FD_ISSET(mysockets[i], &masterset))
|
&& FD_ISSET(mysockets[i], &masterset))
|
||||||
|
@ -1150,11 +1103,9 @@ static void SOCK_CloseSocket(void)
|
||||||
mysockets[i] = ERRSOCKET;
|
mysockets[i] = ERRSOCKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void I_ShutdownTcpDriver(void)
|
void I_ShutdownTcpDriver(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
SOCK_CloseSocket();
|
SOCK_CloseSocket();
|
||||||
|
|
||||||
CONS_Printf("I_ShutdownTcpDriver: ");
|
CONS_Printf("I_ShutdownTcpDriver: ");
|
||||||
|
@ -1164,10 +1115,8 @@ void I_ShutdownTcpDriver(void)
|
||||||
#endif
|
#endif
|
||||||
CONS_Printf("shut down\n");
|
CONS_Printf("shut down\n");
|
||||||
init_tcp_driver = false;
|
init_tcp_driver = false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
{
|
{
|
||||||
SINT8 newnode = -1;
|
SINT8 newnode = -1;
|
||||||
|
@ -1223,17 +1172,13 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
I_freeaddrinfo(ai);
|
I_freeaddrinfo(ai);
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static boolean SOCK_OpenSocket(void)
|
static boolean SOCK_OpenSocket(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
memset(clientaddress, 0, sizeof (clientaddress));
|
memset(clientaddress, 0, sizeof (clientaddress));
|
||||||
|
|
||||||
nodeconnected[0] = true; // always connected to self
|
nodeconnected[0] = true; // always connected to self
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (size_t i = 1; i < MAXNETNODES; i++)
|
||||||
nodeconnected[i] = false;
|
nodeconnected[i] = false;
|
||||||
nodeconnected[BROADCASTADDR] = true;
|
nodeconnected[BROADCASTADDR] = true;
|
||||||
I_NetSend = SOCK_Send;
|
I_NetSend = SOCK_Send;
|
||||||
|
@ -1251,18 +1196,12 @@ static boolean SOCK_OpenSocket(void)
|
||||||
// build the socket but close it first
|
// build the socket but close it first
|
||||||
SOCK_CloseSocket();
|
SOCK_CloseSocket();
|
||||||
return UDP_Socket();
|
return UDP_Socket();
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean SOCK_Ban(INT32 node)
|
static boolean SOCK_Ban(INT32 node)
|
||||||
{
|
{
|
||||||
if (node > MAXNETNODES)
|
if (node > MAXNETNODES)
|
||||||
return false;
|
return false;
|
||||||
#ifdef NONET
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (numbans == MAXBANS)
|
if (numbans == MAXBANS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1281,16 +1220,10 @@ static boolean SOCK_Ban(INT32 node)
|
||||||
#endif
|
#endif
|
||||||
numbans++;
|
numbans++;
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
|
||||||
(void)address;
|
|
||||||
(void)mask;
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
struct my_addrinfo *ai, *runp, hints;
|
struct my_addrinfo *ai, *runp, hints;
|
||||||
int gaie;
|
int gaie;
|
||||||
|
|
||||||
|
@ -1335,7 +1268,6 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
||||||
I_freeaddrinfo(ai);
|
I_freeaddrinfo(ai);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SOCK_ClearBans(void)
|
static void SOCK_ClearBans(void)
|
|
@ -15,13 +15,14 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "doomstat.h"
|
#include "../doomstat.h"
|
||||||
#include "doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "command.h"
|
#include "../command.h"
|
||||||
#include "i_threads.h"
|
#include "../i_threads.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "m_menu.h"
|
#include "client_connection.h"
|
||||||
#include "z_zone.h"
|
#include "../m_menu.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
|
||||||
#ifdef MASTERSERVER
|
#ifdef MASTERSERVER
|
||||||
|
|
||||||
|
@ -45,9 +46,7 @@ static I_cond MSCond;
|
||||||
# define Unlock_state()
|
# define Unlock_state()
|
||||||
#endif/*HAVE_THREADS*/
|
#endif/*HAVE_THREADS*/
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
static void Command_Listserv_f(void);
|
static void Command_Listserv_f(void);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif/*MASTERSERVER*/
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
|
@ -89,7 +88,6 @@ msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test
|
||||||
*/
|
*/
|
||||||
void AddMServCommands(void)
|
void AddMServCommands(void)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
|
||||||
CV_RegisterVar(&cv_masterserver);
|
CV_RegisterVar(&cv_masterserver);
|
||||||
CV_RegisterVar(&cv_masterserver_update_rate);
|
CV_RegisterVar(&cv_masterserver_update_rate);
|
||||||
CV_RegisterVar(&cv_masterserver_timeout);
|
CV_RegisterVar(&cv_masterserver_timeout);
|
||||||
|
@ -100,7 +98,6 @@ void AddMServCommands(void)
|
||||||
COM_AddCommand("listserv", Command_Listserv_f, 0);
|
COM_AddCommand("listserv", Command_Listserv_f, 0);
|
||||||
COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident
|
COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MASTERSERVER
|
#ifdef MASTERSERVER
|
||||||
|
@ -189,7 +186,6 @@ void GetMODVersion_Console(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
/** Gets a list of game servers. Called from console.
|
/** Gets a list of game servers. Called from console.
|
||||||
*/
|
*/
|
||||||
static void Command_Listserv_f(void)
|
static void Command_Listserv_f(void)
|
||||||
|
@ -200,7 +196,6 @@ static void Command_Listserv_f(void)
|
||||||
HMS_list_servers();
|
HMS_list_servers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Finish_registration (void)
|
Finish_registration (void)
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef _MSERV_H_
|
#ifndef _MSERV_H_
|
||||||
#define _MSERV_H_
|
#define _MSERV_H_
|
||||||
|
|
||||||
#include "i_threads.h"
|
#include "../i_threads.h"
|
||||||
|
|
||||||
// lowered from 32 due to menu changes
|
// lowered from 32 due to menu changes
|
||||||
#define NUM_LIST_ROOMS 16
|
#define NUM_LIST_ROOMS 16
|
382
src/netcode/net_command.c
Normal file
382
src/netcode/net_command.c
Normal file
|
@ -0,0 +1,382 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file net_command.c
|
||||||
|
/// \brief Net command handling
|
||||||
|
|
||||||
|
#include "net_command.h"
|
||||||
|
#include "tic_command.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "server_connection.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "../byteptr.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
|
||||||
|
UINT8 localtextcmd[MAXTEXTCMD];
|
||||||
|
UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||||
|
static void (*listnetxcmd[MAXNETXCMD])(UINT8 **p, INT32 playernum);
|
||||||
|
|
||||||
|
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum))
|
||||||
|
{
|
||||||
|
#ifdef PARANOIA
|
||||||
|
if (id >= MAXNETXCMD)
|
||||||
|
I_Error("Command id %d too big", id);
|
||||||
|
if (listnetxcmd[id] != 0)
|
||||||
|
I_Error("Command id %d already used", id);
|
||||||
|
#endif
|
||||||
|
listnetxcmd[id] = cmd_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam)
|
||||||
|
{
|
||||||
|
if (localtextcmd[0]+2+nparam > MAXTEXTCMD)
|
||||||
|
{
|
||||||
|
// for future reference: if (cv_debug) != debug disabled.
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[0], sizeu1(nparam));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localtextcmd[0]++;
|
||||||
|
localtextcmd[localtextcmd[0]] = (UINT8)id;
|
||||||
|
if (param && nparam)
|
||||||
|
{
|
||||||
|
M_Memcpy(&localtextcmd[localtextcmd[0]+1], param, nparam);
|
||||||
|
localtextcmd[0] = (UINT8)(localtextcmd[0] + (UINT8)nparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// splitscreen player
|
||||||
|
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam)
|
||||||
|
{
|
||||||
|
if (localtextcmd2[0]+2+nparam > MAXTEXTCMD)
|
||||||
|
{
|
||||||
|
I_Error("No more place in the buffer for netcmd %d\n",id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localtextcmd2[0]++;
|
||||||
|
localtextcmd2[localtextcmd2[0]] = (UINT8)id;
|
||||||
|
if (param && nparam)
|
||||||
|
{
|
||||||
|
M_Memcpy(&localtextcmd2[localtextcmd2[0]+1], param, nparam);
|
||||||
|
localtextcmd2[0] = (UINT8)(localtextcmd2[0] + (UINT8)nparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 GetFreeXCmdSize(void)
|
||||||
|
{
|
||||||
|
// -1 for the size and another -1 for the ID.
|
||||||
|
return (UINT8)(localtextcmd[0] - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frees all textcmd memory for the specified tic
|
||||||
|
void D_FreeTextcmd(tic_t tic)
|
||||||
|
{
|
||||||
|
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
textcmdtic_t *textcmdtic = *tctprev;
|
||||||
|
|
||||||
|
while (textcmdtic && textcmdtic->tic != tic)
|
||||||
|
{
|
||||||
|
tctprev = &textcmdtic->next;
|
||||||
|
textcmdtic = textcmdtic->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textcmdtic)
|
||||||
|
{
|
||||||
|
// Remove this tic from the list.
|
||||||
|
*tctprev = textcmdtic->next;
|
||||||
|
|
||||||
|
// Free all players.
|
||||||
|
for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++)
|
||||||
|
{
|
||||||
|
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[i];
|
||||||
|
|
||||||
|
while (textcmdplayer)
|
||||||
|
{
|
||||||
|
textcmdplayer_t *tcpnext = textcmdplayer->next;
|
||||||
|
Z_Free(textcmdplayer);
|
||||||
|
textcmdplayer = tcpnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free this tic's own memory.
|
||||||
|
Z_Free(textcmdtic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
||||||
|
UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum)
|
||||||
|
{
|
||||||
|
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next;
|
||||||
|
|
||||||
|
// Do we have an entry for the tic? If so, look for player.
|
||||||
|
if (textcmdtic)
|
||||||
|
{
|
||||||
|
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next;
|
||||||
|
|
||||||
|
if (textcmdplayer) return textcmdplayer->cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the buffer for the specified ticcmd, creating one if necessary
|
||||||
|
UINT8* D_GetTextcmd(tic_t tic, INT32 playernum)
|
||||||
|
{
|
||||||
|
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
textcmdplayer_t *textcmdplayer, **tcpprev;
|
||||||
|
|
||||||
|
// Look for the tic.
|
||||||
|
while (textcmdtic && textcmdtic->tic != tic)
|
||||||
|
{
|
||||||
|
tctprev = &textcmdtic->next;
|
||||||
|
textcmdtic = textcmdtic->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have an entry for the tic, make it.
|
||||||
|
if (!textcmdtic)
|
||||||
|
{
|
||||||
|
textcmdtic = *tctprev = Z_Calloc(sizeof (textcmdtic_t), PU_STATIC, NULL);
|
||||||
|
textcmdtic->tic = tic;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpprev = &textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
textcmdplayer = *tcpprev;
|
||||||
|
|
||||||
|
// Look for the player.
|
||||||
|
while (textcmdplayer && textcmdplayer->playernum != playernum)
|
||||||
|
{
|
||||||
|
tcpprev = &textcmdplayer->next;
|
||||||
|
textcmdplayer = textcmdplayer->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have an entry for the player, make it.
|
||||||
|
if (!textcmdplayer)
|
||||||
|
{
|
||||||
|
textcmdplayer = *tcpprev = Z_Calloc(sizeof (textcmdplayer_t), PU_STATIC, NULL);
|
||||||
|
textcmdplayer->playernum = playernum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return textcmdplayer->cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtraDataTicker(void)
|
||||||
|
{
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playeringame[i] || i == 0)
|
||||||
|
{
|
||||||
|
UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i);
|
||||||
|
|
||||||
|
if (bufferstart)
|
||||||
|
{
|
||||||
|
UINT8 *curpos = bufferstart;
|
||||||
|
UINT8 *bufferend = &curpos[curpos[0]+1];
|
||||||
|
|
||||||
|
curpos++;
|
||||||
|
while (curpos < bufferend)
|
||||||
|
{
|
||||||
|
if (*curpos < MAXNETXCMD && listnetxcmd[*curpos])
|
||||||
|
{
|
||||||
|
const UINT8 id = *curpos;
|
||||||
|
curpos++;
|
||||||
|
DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], i));
|
||||||
|
(listnetxcmd[id])(&curpos, i);
|
||||||
|
DEBFILE("done\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
||||||
|
}
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you are a client, you can safely forget the net commands for this tic
|
||||||
|
// If you are the server, you need to remember them until every client has been acknowledged,
|
||||||
|
// because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it
|
||||||
|
if (client)
|
||||||
|
D_FreeTextcmd(gametic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// used at txtcmds received to check packetsize bound
|
||||||
|
size_t TotalTextCmdPerTic(tic_t tic)
|
||||||
|
{
|
||||||
|
size_t total = 1; // num of textcmds in the tic (ntextcmd byte)
|
||||||
|
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
UINT8 *textcmd = D_GetExistingTextcmd(tic, i);
|
||||||
|
if ((!i || playeringame[i]) && textcmd)
|
||||||
|
total += 2 + textcmd[0]; // "+2" for size and playernum
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_TextCmd(SINT8 node, INT32 netconsole)
|
||||||
|
{
|
||||||
|
if (client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// splitscreen special
|
||||||
|
if (netbuffer->packettype == PT_TEXTCMD2)
|
||||||
|
netconsole = netnodes[node].player2;
|
||||||
|
|
||||||
|
if (netconsole < 0 || netconsole >= MAXPLAYERS)
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
tic_t tic = maketic;
|
||||||
|
UINT8 *textcmd;
|
||||||
|
|
||||||
|
// ignore if the textcmd has a reported size of zero
|
||||||
|
// this shouldn't be sent at all
|
||||||
|
if (!netbuffer->u.textcmd[0])
|
||||||
|
{
|
||||||
|
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||||
|
node, netconsole));
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore if the textcmd size var is actually larger than it should be
|
||||||
|
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||||
|
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||||
|
{
|
||||||
|
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||||
|
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||||
|
node, netconsole));
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if tic that we are making isn't too large else we cannot send it :(
|
||||||
|
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||||
|
j = software_MAXPACKETLENGTH
|
||||||
|
- (netbuffer->u.textcmd[0]+2+BASESERVERTICSSIZE
|
||||||
|
+ (doomcom->numslots+1)*sizeof(ticcmd_t));
|
||||||
|
|
||||||
|
// search a tic that have enougth space in the ticcmd
|
||||||
|
while ((textcmd = D_GetExistingTextcmd(tic, netconsole)),
|
||||||
|
(TotalTextCmdPerTic(tic) > j || netbuffer->u.textcmd[0] + (textcmd ? textcmd[0] : 0) > MAXTEXTCMD)
|
||||||
|
&& tic < firstticstosend + BACKUPTICS)
|
||||||
|
tic++;
|
||||||
|
|
||||||
|
if (tic >= firstticstosend + BACKUPTICS)
|
||||||
|
{
|
||||||
|
DEBFILE(va("GetPacket: Textcmd too long (max %s, used %s, mak %d, "
|
||||||
|
"tosend %u, node %u, player %d)\n", sizeu1(j), sizeu2(TotalTextCmdPerTic(maketic)),
|
||||||
|
maketic, firstticstosend, node, netconsole));
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have a buffer
|
||||||
|
if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole);
|
||||||
|
|
||||||
|
DEBFILE(va("textcmd put in tic %u at position %d (player %d) ftts %u mk %u\n",
|
||||||
|
tic, textcmd[0]+1, netconsole, firstticstosend, maketic));
|
||||||
|
|
||||||
|
M_Memcpy(&textcmd[textcmd[0]+1], netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]);
|
||||||
|
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf)
|
||||||
|
{
|
||||||
|
UINT8 *numcmds;
|
||||||
|
|
||||||
|
numcmds = (*buf)++;
|
||||||
|
*numcmds = 0;
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
UINT8 *cmd = D_GetExistingTextcmd(tic, i);
|
||||||
|
INT32 size = cmd ? cmd[0] : 0;
|
||||||
|
|
||||||
|
if ((!i || playeringame[i]) && size)
|
||||||
|
{
|
||||||
|
(*numcmds)++;
|
||||||
|
WRITEUINT8(*buf, i);
|
||||||
|
M_Memcpy(*buf, cmd, size + 1);
|
||||||
|
*buf += size + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf)
|
||||||
|
{
|
||||||
|
UINT8 numcmds = *(*buf)++;
|
||||||
|
|
||||||
|
for (UINT32 i = 0; i < numcmds; i++)
|
||||||
|
{
|
||||||
|
INT32 playernum = *(*buf)++; // playernum
|
||||||
|
size_t size = (*buf)[0]+1;
|
||||||
|
|
||||||
|
if (tic >= gametic) // Don't copy old net commands
|
||||||
|
M_Memcpy(D_GetTextcmd(tic, playernum), *buf, size);
|
||||||
|
*buf += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_SendNetCommands(void)
|
||||||
|
{
|
||||||
|
// Send extra data if needed
|
||||||
|
if (localtextcmd[0])
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_TEXTCMD;
|
||||||
|
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
||||||
|
// All extra data have been sent
|
||||||
|
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail...
|
||||||
|
localtextcmd[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send extra data if needed for player 2 (splitscreen)
|
||||||
|
if (localtextcmd2[0])
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_TEXTCMD2;
|
||||||
|
M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1);
|
||||||
|
// All extra data have been sent
|
||||||
|
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail...
|
||||||
|
localtextcmd2[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendKick(UINT8 playernum, UINT8 msg)
|
||||||
|
{
|
||||||
|
UINT8 buf[2];
|
||||||
|
|
||||||
|
if (!(server && cv_rejointimeout.value))
|
||||||
|
msg &= ~KICK_MSG_KEEP_BODY;
|
||||||
|
|
||||||
|
buf[0] = playernum;
|
||||||
|
buf[1] = msg;
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendKicksForNode(SINT8 node, UINT8 msg)
|
||||||
|
{
|
||||||
|
if (!netnodes[node].ingame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (INT32 playernum = netnodes[node].player; playernum != -1; playernum = netnodes[node].player2)
|
||||||
|
if (playernum != -1 && playeringame[playernum])
|
||||||
|
SendKick(playernum, msg);
|
||||||
|
}
|
66
src/netcode/net_command.h
Normal file
66
src/netcode/net_command.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file net_command.h
|
||||||
|
/// \brief Net command handling
|
||||||
|
|
||||||
|
#ifndef __D_NET_COMMAND__
|
||||||
|
#define __D_NET_COMMAND__
|
||||||
|
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
// Must be a power of two
|
||||||
|
#define TEXTCMD_HASH_SIZE 4
|
||||||
|
|
||||||
|
typedef struct textcmdplayer_s
|
||||||
|
{
|
||||||
|
INT32 playernum;
|
||||||
|
UINT8 cmd[MAXTEXTCMD];
|
||||||
|
struct textcmdplayer_s *next;
|
||||||
|
} textcmdplayer_t;
|
||||||
|
|
||||||
|
typedef struct textcmdtic_s
|
||||||
|
{
|
||||||
|
tic_t tic;
|
||||||
|
textcmdplayer_t *playercmds[TEXTCMD_HASH_SIZE];
|
||||||
|
struct textcmdtic_s *next;
|
||||||
|
} textcmdtic_t;
|
||||||
|
|
||||||
|
extern textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE];
|
||||||
|
|
||||||
|
extern UINT8 localtextcmd[MAXTEXTCMD];
|
||||||
|
extern UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||||
|
|
||||||
|
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
||||||
|
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
|
||||||
|
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
|
||||||
|
|
||||||
|
UINT8 GetFreeXCmdSize(void);
|
||||||
|
void D_FreeTextcmd(tic_t tic);
|
||||||
|
|
||||||
|
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
||||||
|
UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum);
|
||||||
|
|
||||||
|
// Gets the buffer for the specified ticcmd, creating one if necessary
|
||||||
|
UINT8* D_GetTextcmd(tic_t tic, INT32 playernum);
|
||||||
|
|
||||||
|
void ExtraDataTicker(void);
|
||||||
|
|
||||||
|
// used at txtcmds received to check packetsize bound
|
||||||
|
size_t TotalTextCmdPerTic(tic_t tic);
|
||||||
|
|
||||||
|
void PT_TextCmd(SINT8 node, INT32 netconsole);
|
||||||
|
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf);
|
||||||
|
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf);
|
||||||
|
void CL_SendNetCommands(void);
|
||||||
|
void SendKick(UINT8 playernum, UINT8 msg);
|
||||||
|
void SendKicksForNode(SINT8 node, UINT8 msg);
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,19 +7,15 @@
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
// See the 'LICENSE' file for more details.
|
// See the 'LICENSE' file for more details.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/// \file d_clisrv.h
|
/// \file protocol.h
|
||||||
/// \brief high level networking stuff
|
/// \brief Data exchanged through the network
|
||||||
|
|
||||||
#ifndef __D_CLISRV__
|
#ifndef __PROTOCOL__
|
||||||
#define __D_CLISRV__
|
#define __PROTOCOL__
|
||||||
|
|
||||||
#include "d_ticcmd.h"
|
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_netcmd.h"
|
#include "../d_ticcmd.h"
|
||||||
#include "d_net.h"
|
#include "../doomdef.h"
|
||||||
#include "tables.h"
|
|
||||||
#include "d_player.h"
|
|
||||||
#include "mserv.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The 'packet version' is used to distinguish packet
|
The 'packet version' is used to distinguish packet
|
||||||
|
@ -38,10 +34,9 @@ therein, increment this number.
|
||||||
// one that defines the actual packets to
|
// one that defines the actual packets to
|
||||||
// be transmitted.
|
// be transmitted.
|
||||||
|
|
||||||
// Networking and tick handling related.
|
|
||||||
#define BACKUPTICS 1024
|
#define BACKUPTICS 1024
|
||||||
#define CLIENTBACKUPTICS 32
|
|
||||||
#define MAXTEXTCMD 256
|
#define MAXTEXTCMD 256
|
||||||
|
|
||||||
//
|
//
|
||||||
// Packet structure
|
// Packet structure
|
||||||
//
|
//
|
||||||
|
@ -77,7 +72,7 @@ typedef enum
|
||||||
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
||||||
PT_HASLUAFILE, // Client telling the server they have the file
|
PT_HASLUAFILE, // Client telling the server they have the file
|
||||||
|
|
||||||
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
PT_BASICKEEPALIVE, // Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||||
|
|
||||||
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
||||||
|
|
||||||
|
@ -92,7 +87,6 @@ typedef enum
|
||||||
PT_TEXTCMD, // Extra text commands from the client.
|
PT_TEXTCMD, // Extra text commands from the client.
|
||||||
PT_TEXTCMD2, // Splitscreen text commands.
|
PT_TEXTCMD2, // Splitscreen text commands.
|
||||||
PT_CLIENTJOIN, // Client wants to join; used in start game.
|
PT_CLIENTJOIN, // Client wants to join; used in start game.
|
||||||
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
|
||||||
|
|
||||||
PT_LOGIN, // Login attempt from the client.
|
PT_LOGIN, // Login attempt from the client.
|
||||||
|
|
||||||
|
@ -103,14 +97,6 @@ typedef enum
|
||||||
NUMPACKETTYPE
|
NUMPACKETTYPE
|
||||||
} packettype_t;
|
} packettype_t;
|
||||||
|
|
||||||
#ifdef PACKETDROP
|
|
||||||
void Command_Drop(void);
|
|
||||||
void Command_Droprate(void);
|
|
||||||
#endif
|
|
||||||
#ifdef _DEBUG
|
|
||||||
void Command_Numnodes(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,13 +125,12 @@ typedef struct
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Server to client packet
|
// Server to client packet
|
||||||
// this packet is too large
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
tic_t starttic;
|
tic_t starttic;
|
||||||
UINT8 numtics;
|
UINT8 numtics;
|
||||||
UINT8 numslots; // "Slots filled": Highest player number in use plus one.
|
UINT8 numslots; // "Slots filled": Highest player number in use plus one.
|
||||||
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
|
ticcmd_t cmds[45];
|
||||||
} ATTRPACK servertics_pak;
|
} ATTRPACK servertics_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -215,6 +200,7 @@ enum {
|
||||||
|
|
||||||
#define MAXSERVERNAME 32
|
#define MAXSERVERNAME 32
|
||||||
#define MAXFILENEEDED 915
|
#define MAXFILENEEDED 915
|
||||||
|
|
||||||
// This packet is too large
|
// This packet is too large
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -275,7 +261,7 @@ typedef struct
|
||||||
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
|
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
|
||||||
UINT32 score;
|
UINT32 score;
|
||||||
UINT16 timeinserver; // In seconds.
|
UINT16 timeinserver; // In seconds.
|
||||||
} ATTRPACK plrinfo;
|
} ATTRPACK plrinfo_pak;
|
||||||
|
|
||||||
// Shortest player information for join during intermission.
|
// Shortest player information for join during intermission.
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -286,7 +272,7 @@ typedef struct
|
||||||
UINT32 pflags;
|
UINT32 pflags;
|
||||||
UINT32 score;
|
UINT32 score;
|
||||||
UINT8 ctfteam;
|
UINT8 ctfteam;
|
||||||
} ATTRPACK plrconfig;
|
} ATTRPACK plrconfig_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -309,25 +295,25 @@ typedef struct
|
||||||
UINT8 reserved; // Padding
|
UINT8 reserved; // Padding
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
clientcmd_pak clientpak; // 144 bytes
|
clientcmd_pak clientpak;
|
||||||
client2cmd_pak client2pak; // 200 bytes
|
client2cmd_pak client2pak;
|
||||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
servertics_pak serverpak;
|
||||||
serverconfig_pak servercfg; // 773 bytes
|
serverconfig_pak servercfg;
|
||||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
UINT8 textcmd[MAXTEXTCMD+1];
|
||||||
filetx_pak filetxpak; // 139 bytes
|
filetx_pak filetxpak;
|
||||||
fileack_pak fileack;
|
fileack_pak fileack;
|
||||||
UINT8 filereceived;
|
UINT8 filereceived;
|
||||||
clientconfig_pak clientcfg; // 136 bytes
|
clientconfig_pak clientcfg;
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
serverinfo_pak serverinfo; // 1024 bytes
|
serverinfo_pak serverinfo;
|
||||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
serverrefuse_pak serverrefuse;
|
||||||
askinfo_pak askinfo; // 61 bytes
|
askinfo_pak askinfo;
|
||||||
msaskinfo_pak msaskinfo; // 22 bytes
|
msaskinfo_pak msaskinfo;
|
||||||
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
|
plrinfo_pak playerinfo[MAXPLAYERS];
|
||||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
plrconfig_pak playerconfig[MAXPLAYERS];
|
||||||
INT32 filesneedednum; // 4 bytes
|
INT32 filesneedednum;
|
||||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
filesneededconfig_pak filesneededcfg;
|
||||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
UINT32 pingtable[MAXPLAYERS+1];
|
||||||
} u; // This is needed to pack diff packet types data together
|
} u; // This is needed to pack diff packet types data together
|
||||||
} ATTRPACK doomdata_t;
|
} ATTRPACK doomdata_t;
|
||||||
|
|
||||||
|
@ -335,26 +321,7 @@ typedef struct
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAXSERVERLIST (MAXNETNODES-1)
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SINT8 node;
|
|
||||||
serverinfo_pak info;
|
|
||||||
} serverelem_t;
|
|
||||||
|
|
||||||
extern serverelem_t serverlist[MAXSERVERLIST];
|
|
||||||
extern UINT32 serverlistcount;
|
|
||||||
extern INT32 mapchangepending;
|
|
||||||
|
|
||||||
// Points inside doomcom
|
|
||||||
extern doomdata_t *netbuffer;
|
|
||||||
|
|
||||||
extern consvar_t cv_showjoinaddress;
|
|
||||||
extern consvar_t cv_playbackspeed;
|
|
||||||
|
|
||||||
#define BASEPACKETSIZE offsetof(doomdata_t, u)
|
|
||||||
#define FILETXHEADER offsetof(filetx_pak, data)
|
#define FILETXHEADER offsetof(filetx_pak, data)
|
||||||
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
|
|
||||||
|
|
||||||
#define KICK_MSG_GO_AWAY 1
|
#define KICK_MSG_GO_AWAY 1
|
||||||
#define KICK_MSG_CON_FAIL 2
|
#define KICK_MSG_CON_FAIL 2
|
||||||
|
@ -366,107 +333,4 @@ extern consvar_t cv_playbackspeed;
|
||||||
#define KICK_MSG_CUSTOM_BAN 8
|
#define KICK_MSG_CUSTOM_BAN 8
|
||||||
#define KICK_MSG_KEEP_BODY 0x80
|
#define KICK_MSG_KEEP_BODY 0x80
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
KR_KICK = 1, //Kicked by server
|
|
||||||
KR_PINGLIMIT = 2, //Broke Ping Limit
|
|
||||||
KR_SYNCH = 3, //Synch Failure
|
|
||||||
KR_TIMEOUT = 4, //Connection Timeout
|
|
||||||
KR_BAN = 5, //Banned by server
|
|
||||||
KR_LEAVE = 6, //Quit the game
|
|
||||||
|
|
||||||
} kickreason_t;
|
|
||||||
|
|
||||||
/* the max number of name changes in some time period */
|
|
||||||
#define MAXNAMECHANGES (5)
|
|
||||||
#define NAMECHANGERATE (60*TICRATE)
|
|
||||||
|
|
||||||
extern boolean server;
|
|
||||||
extern boolean serverrunning;
|
|
||||||
#define client (!server)
|
|
||||||
extern boolean dedicated; // For dedicated server
|
|
||||||
extern UINT16 software_MAXPACKETLENGTH;
|
|
||||||
extern boolean acceptnewnode;
|
|
||||||
extern SINT8 servernode;
|
|
||||||
|
|
||||||
void Command_Ping_f(void);
|
|
||||||
extern tic_t connectiontimeout;
|
|
||||||
extern tic_t jointimeout;
|
|
||||||
extern UINT16 pingmeasurecount;
|
|
||||||
extern UINT32 realpingtable[MAXPLAYERS];
|
|
||||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
|
||||||
extern tic_t servermaxping;
|
|
||||||
|
|
||||||
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
|
|
||||||
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
|
||||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
|
||||||
extern consvar_t cv_dedicatedidletime;
|
|
||||||
|
|
||||||
// Used in d_net, the only dependence
|
|
||||||
tic_t ExpandTics(INT32 low, INT32 node);
|
|
||||||
void D_ClientServerInit(void);
|
|
||||||
|
|
||||||
// Initialise the other field
|
|
||||||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
|
||||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
|
|
||||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
|
|
||||||
void SendKick(UINT8 playernum, UINT8 msg);
|
|
||||||
|
|
||||||
// Create any new ticcmds and broadcast to other players.
|
|
||||||
void NetUpdate(void);
|
|
||||||
|
|
||||||
// Maintain connections to nodes without timing them all out.
|
|
||||||
void NetKeepAlive(void);
|
|
||||||
|
|
||||||
void SV_StartSinglePlayerServer(void);
|
|
||||||
boolean SV_SpawnServer(void);
|
|
||||||
void SV_StopServer(void);
|
|
||||||
void SV_ResetServer(void);
|
|
||||||
void CL_AddSplitscreenPlayer(void);
|
|
||||||
void CL_RemoveSplitscreenPlayer(void);
|
|
||||||
void CL_Reset(void);
|
|
||||||
void CL_ClearPlayer(INT32 playernum);
|
|
||||||
void CL_QueryServerList(msg_server_t *list);
|
|
||||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
|
||||||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
|
||||||
// Is there a game running
|
|
||||||
boolean Playing(void);
|
|
||||||
|
|
||||||
// Broadcasts special packets to other players
|
|
||||||
// to notify of game exit
|
|
||||||
void D_QuitNetGame(void);
|
|
||||||
|
|
||||||
//? How many ticks to run?
|
|
||||||
boolean TryRunTics(tic_t realtic);
|
|
||||||
|
|
||||||
// extra data for lmps
|
|
||||||
// these functions scare me. they contain magic.
|
|
||||||
/*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum);
|
|
||||||
void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/
|
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// translate a playername in a player number return -1 if not found and
|
|
||||||
// print a error message in the console
|
|
||||||
SINT8 nametonum(const char *name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern char motd[254], server_context[8];
|
|
||||||
extern UINT8 playernode[MAXPLAYERS];
|
|
||||||
|
|
||||||
INT32 D_NumPlayers(void);
|
|
||||||
INT32 D_NumBots(void);
|
|
||||||
void D_ResetTiccmds(void);
|
|
||||||
|
|
||||||
tic_t GetLag(INT32 node);
|
|
||||||
UINT8 GetFreeXCmdSize(void);
|
|
||||||
|
|
||||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
|
||||||
|
|
||||||
extern UINT8 hu_redownloadinggamestate;
|
|
||||||
|
|
||||||
extern UINT8 adminpassmd5[16];
|
|
||||||
extern boolean adminpasswordset;
|
|
||||||
|
|
||||||
extern boolean hu_stopped;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
507
src/netcode/server_connection.c
Normal file
507
src/netcode/server_connection.c
Normal file
|
@ -0,0 +1,507 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file server_connection.c
|
||||||
|
/// \brief Server-side part of connection handling
|
||||||
|
|
||||||
|
#include "server_connection.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "d_netfil.h"
|
||||||
|
#include "mserv.h"
|
||||||
|
#include "net_command.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "../byteptr.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../g_state.h"
|
||||||
|
#include "../p_setup.h"
|
||||||
|
#include "../p_tick.h"
|
||||||
|
#include "../command.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
|
||||||
|
// Minimum timeout for sending the savegame
|
||||||
|
// The actual timeout will be longer depending on the savegame length
|
||||||
|
tic_t jointimeout = (10*TICRATE);
|
||||||
|
|
||||||
|
// Incremented by cv_joindelay when a client joins, decremented each tic.
|
||||||
|
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
|
||||||
|
tic_t joindelay = 0;
|
||||||
|
|
||||||
|
// Minimum timeout for sending the savegame
|
||||||
|
// The actual timeout will be longer depending on the savegame length
|
||||||
|
char playeraddress[MAXPLAYERS][64];
|
||||||
|
|
||||||
|
consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, maxplayers_cons_t, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
|
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
|
consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "2", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL);
|
||||||
|
|
||||||
|
static INT32 FindRejoinerNum(SINT8 node)
|
||||||
|
{
|
||||||
|
char addressbuffer[64];
|
||||||
|
const char *nodeaddress;
|
||||||
|
const char *strippednodeaddress;
|
||||||
|
|
||||||
|
// Make sure there is no dead dress before proceeding to the stripping
|
||||||
|
if (!I_GetNodeAddress)
|
||||||
|
return -1;
|
||||||
|
nodeaddress = I_GetNodeAddress(node);
|
||||||
|
if (!nodeaddress)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Strip the address of its port
|
||||||
|
strcpy(addressbuffer, nodeaddress);
|
||||||
|
strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
|
||||||
|
|
||||||
|
// Check if any player matches the stripped address
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
|
||||||
|
&& !strcmp(playeraddress[i], strippednodeaddress))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT8
|
||||||
|
GetRefuseReason (INT32 node)
|
||||||
|
{
|
||||||
|
if (!node || FindRejoinerNum(node) != -1)
|
||||||
|
return 0;
|
||||||
|
else if (bannednode && bannednode[node])
|
||||||
|
return REFUSE_BANNED;
|
||||||
|
else if (!cv_allownewplayer.value)
|
||||||
|
return REFUSE_JOINS_DISABLED;
|
||||||
|
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||||
|
return REFUSE_SLOTS_FULL;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
|
{
|
||||||
|
UINT8 *p;
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_SERVERINFO;
|
||||||
|
netbuffer->u.serverinfo._255 = 255;
|
||||||
|
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
|
||||||
|
netbuffer->u.serverinfo.version = VERSION;
|
||||||
|
netbuffer->u.serverinfo.subversion = SUBVERSION;
|
||||||
|
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
|
||||||
|
sizeof netbuffer->u.serverinfo.application);
|
||||||
|
// return back the time value so client can compute their ping
|
||||||
|
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
|
||||||
|
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
||||||
|
|
||||||
|
// Exclude bots from both counts
|
||||||
|
netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots());
|
||||||
|
netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots());
|
||||||
|
|
||||||
|
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
|
||||||
|
|
||||||
|
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
|
||||||
|
sizeof netbuffer->u.serverinfo.gametypename);
|
||||||
|
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||||
|
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||||
|
netbuffer->u.serverinfo.flags = (dedicated ? SV_DEDICATED : 0);
|
||||||
|
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||||
|
MAXSERVERNAME);
|
||||||
|
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||||
|
|
||||||
|
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||||
|
|
||||||
|
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle);
|
||||||
|
|
||||||
|
if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl)
|
||||||
|
{
|
||||||
|
char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
|
||||||
|
while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0')
|
||||||
|
{
|
||||||
|
if (!(*read & 0x80))
|
||||||
|
{
|
||||||
|
*writ = toupper(*read);
|
||||||
|
writ++;
|
||||||
|
}
|
||||||
|
read++;
|
||||||
|
}
|
||||||
|
*writ = '\0';
|
||||||
|
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
|
||||||
|
|
||||||
|
if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||||
|
netbuffer->u.serverinfo.iszone = 1;
|
||||||
|
else
|
||||||
|
netbuffer->u.serverinfo.iszone = 0;
|
||||||
|
|
||||||
|
if (mapheaderinfo[gamemap-1])
|
||||||
|
netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||||
|
|
||||||
|
p = PutFileNeeded(0);
|
||||||
|
|
||||||
|
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SV_SendPlayerInfo(INT32 node)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_PLAYERINFO;
|
||||||
|
|
||||||
|
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i])
|
||||||
|
{
|
||||||
|
netbuffer->u.playerinfo[i].num = 255; // This slot is empty.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
netbuffer->u.playerinfo[i].num = i;
|
||||||
|
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||||
|
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||||
|
|
||||||
|
//fetch IP address
|
||||||
|
//No, don't do that, you fuckface.
|
||||||
|
memset(netbuffer->u.playerinfo[i].address, 0, 4);
|
||||||
|
|
||||||
|
if (G_GametypeHasTeams())
|
||||||
|
{
|
||||||
|
if (!players[i].ctfteam)
|
||||||
|
netbuffer->u.playerinfo[i].team = 255;
|
||||||
|
else
|
||||||
|
netbuffer->u.playerinfo[i].team = (UINT8)players[i].ctfteam;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (players[i].spectator)
|
||||||
|
netbuffer->u.playerinfo[i].team = 255;
|
||||||
|
else
|
||||||
|
netbuffer->u.playerinfo[i].team = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
netbuffer->u.playerinfo[i].score = LONG(players[i].score);
|
||||||
|
netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE));
|
||||||
|
netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin
|
||||||
|
#ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself
|
||||||
|
% 3
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
// Extra data
|
||||||
|
netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor;
|
||||||
|
|
||||||
|
if (players[i].pflags & PF_TAGIT)
|
||||||
|
netbuffer->u.playerinfo[i].data |= 0x20;
|
||||||
|
|
||||||
|
if (players[i].gotflag)
|
||||||
|
netbuffer->u.playerinfo[i].data |= 0x40;
|
||||||
|
|
||||||
|
if (players[i].powers[pw_super])
|
||||||
|
netbuffer->u.playerinfo[i].data |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
HSendPacket(node, false, 0, sizeof(plrinfo_pak) * MAXPLAYERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sends a PT_SERVERCFG packet
|
||||||
|
*
|
||||||
|
* \param node The destination
|
||||||
|
* \return True if the packet was successfully sent
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static boolean SV_SendServerConfig(INT32 node)
|
||||||
|
{
|
||||||
|
boolean waspacketsent;
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_SERVERCFG;
|
||||||
|
|
||||||
|
netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer;
|
||||||
|
netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots);
|
||||||
|
netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic);
|
||||||
|
netbuffer->u.servercfg.clientnode = (UINT8)node;
|
||||||
|
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
||||||
|
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||||
|
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||||
|
netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats;
|
||||||
|
|
||||||
|
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||||
|
|
||||||
|
{
|
||||||
|
const size_t len = sizeof (serverconfig_pak);
|
||||||
|
|
||||||
|
#ifdef DEBUGFILE
|
||||||
|
if (debugfile)
|
||||||
|
{
|
||||||
|
fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n",
|
||||||
|
sizeu1(len), node);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
waspacketsent = HSendPacket(node, true, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUGFILE
|
||||||
|
if (debugfile)
|
||||||
|
{
|
||||||
|
if (waspacketsent)
|
||||||
|
{
|
||||||
|
fprintf(debugfile, "ServerConfig Packet was sent\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(debugfile, "ServerConfig Packet could not be sent right now\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return waspacketsent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a node to the game (player will follow at map change or at savegame....)
|
||||||
|
static inline void SV_AddNode(INT32 node)
|
||||||
|
{
|
||||||
|
netnodes[node].tic = gametic;
|
||||||
|
netnodes[node].supposedtic = gametic;
|
||||||
|
// little hack because the server connects to itself and puts
|
||||||
|
// nodeingame when connected not here
|
||||||
|
if (node)
|
||||||
|
netnodes[node].ingame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SV_AddPlayer(SINT8 node, const char *name)
|
||||||
|
{
|
||||||
|
INT32 n;
|
||||||
|
UINT8 buf[2 + MAXPLAYERNAME];
|
||||||
|
UINT8 *p;
|
||||||
|
INT32 newplayernum;
|
||||||
|
|
||||||
|
newplayernum = FindRejoinerNum(node);
|
||||||
|
if (newplayernum == -1)
|
||||||
|
{
|
||||||
|
// search for a free playernum
|
||||||
|
// we can't use playeringame since it is not updated here
|
||||||
|
for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++)
|
||||||
|
{
|
||||||
|
if (playeringame[newplayernum])
|
||||||
|
continue;
|
||||||
|
for (n = 0; n < MAXNETNODES; n++)
|
||||||
|
if (netnodes[n].player == newplayernum || netnodes[n].player2 == newplayernum)
|
||||||
|
break;
|
||||||
|
if (n == MAXNETNODES)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never happen since we check the playernum
|
||||||
|
// before accepting the join
|
||||||
|
I_Assert(newplayernum < MAXPLAYERS);
|
||||||
|
|
||||||
|
playernode[newplayernum] = (UINT8)node;
|
||||||
|
|
||||||
|
p = buf + 2;
|
||||||
|
buf[0] = (UINT8)node;
|
||||||
|
buf[1] = newplayernum;
|
||||||
|
if (netnodes[node].numplayers < 1)
|
||||||
|
{
|
||||||
|
netnodes[node].player = newplayernum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netnodes[node].player2 = newplayernum;
|
||||||
|
buf[1] |= 0x80;
|
||||||
|
}
|
||||||
|
WRITESTRINGN(p, name, MAXPLAYERNAME);
|
||||||
|
netnodes[node].numplayers++;
|
||||||
|
|
||||||
|
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||||
|
|
||||||
|
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SV_SendRefuse(INT32 node, const char *reason)
|
||||||
|
{
|
||||||
|
strcpy(netbuffer->u.serverrefuse.reason, reason);
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_SERVERREFUSE;
|
||||||
|
HSendPacket(node, true, 0, strlen(netbuffer->u.serverrefuse.reason) + 1);
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
GetRefuseMessage (SINT8 node, INT32 rejoinernum)
|
||||||
|
{
|
||||||
|
clientconfig_pak *cc = &netbuffer->u.clientcfg;
|
||||||
|
|
||||||
|
boolean rejoining = (rejoinernum != -1);
|
||||||
|
|
||||||
|
if (!node)/* server connecting to itself */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (
|
||||||
|
cc->modversion != MODVERSION ||
|
||||||
|
strncmp(cc->application, SRB2APPLICATION,
|
||||||
|
sizeof cc->application)
|
||||||
|
){
|
||||||
|
return/* this is probably client's fault */
|
||||||
|
"Incompatible.";
|
||||||
|
}
|
||||||
|
else if (bannednode && bannednode[node])
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"You have been banned\n"
|
||||||
|
"from the server.";
|
||||||
|
}
|
||||||
|
else if (cc->localplayers != 1)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"Wrong player count.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rejoining)
|
||||||
|
{
|
||||||
|
if (!cv_allownewplayer.value)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"The server is not accepting\n"
|
||||||
|
"joins for the moment.";
|
||||||
|
}
|
||||||
|
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||||
|
{
|
||||||
|
return va(
|
||||||
|
"Maximum players reached: %d",
|
||||||
|
cv_maxplayers.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luafiletransfers)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"The serveris broadcasting a file\n"
|
||||||
|
"requested by a Lua script.\n"
|
||||||
|
"Please wait a bit and then\n"
|
||||||
|
"try rejoining.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
const tic_t th = 2 * cv_joindelay.value * TICRATE;
|
||||||
|
|
||||||
|
if (joindelay > th)
|
||||||
|
{
|
||||||
|
return va(
|
||||||
|
"Too many people are connecting.\n"
|
||||||
|
"Please wait %d seconds and then\n"
|
||||||
|
"try rejoining.",
|
||||||
|
(joindelay - th) / TICRATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when a PT_CLIENTJOIN packet is received
|
||||||
|
*
|
||||||
|
* \param node The packet sender
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void PT_ClientJoin(SINT8 node)
|
||||||
|
{
|
||||||
|
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||||
|
INT32 numplayers = netbuffer->u.clientcfg.localplayers;
|
||||||
|
INT32 rejoinernum;
|
||||||
|
|
||||||
|
// Ignore duplicate packets
|
||||||
|
if (client || netnodes[node].ingame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rejoinernum = FindRejoinerNum(node);
|
||||||
|
|
||||||
|
const char *refuse = GetRefuseMessage(node, rejoinernum);
|
||||||
|
if (refuse)
|
||||||
|
{
|
||||||
|
SV_SendRefuse(node, refuse);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (INT32 i = 0; i < numplayers; i++)
|
||||||
|
{
|
||||||
|
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||||
|
if (!EnsurePlayerNameIsGood(names[i], rejoinernum))
|
||||||
|
{
|
||||||
|
SV_SendRefuse(node, "Bad player name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SV_AddNode(node);
|
||||||
|
|
||||||
|
if (!SV_SendServerConfig(node))
|
||||||
|
{
|
||||||
|
/// \note Shouldn't SV_SendRefuse be called before ResetNode?
|
||||||
|
ResetNode(node);
|
||||||
|
SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again"));
|
||||||
|
/// \todo fix this !!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DEBFILE("new node joined\n");
|
||||||
|
|
||||||
|
if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)
|
||||||
|
{
|
||||||
|
SV_SendSaveGame(node, false); // send a complete game state
|
||||||
|
DEBFILE("send savegame\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splitscreen can allow 2 players in one node
|
||||||
|
for (INT32 i = 0; i < numplayers; i++)
|
||||||
|
SV_AddPlayer(node, names[i]);
|
||||||
|
|
||||||
|
joindelay += cv_joindelay.value * TICRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_AskInfoViaMS(SINT8 node)
|
||||||
|
{
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_TellFilesNeeded(SINT8 node)
|
||||||
|
{
|
||||||
|
if (server && serverrunning)
|
||||||
|
{
|
||||||
|
UINT8 *p;
|
||||||
|
INT32 firstfile = netbuffer->u.filesneedednum;
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_MOREFILESNEEDED;
|
||||||
|
netbuffer->u.filesneededcfg.first = firstfile;
|
||||||
|
netbuffer->u.filesneededcfg.more = 0;
|
||||||
|
|
||||||
|
p = PutFileNeeded(firstfile);
|
||||||
|
|
||||||
|
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||||
|
}
|
||||||
|
else // Shouldn't get this if you aren't the server...?
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_AskInfo(SINT8 node)
|
||||||
|
{
|
||||||
|
if (server && serverrunning)
|
||||||
|
{
|
||||||
|
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||||
|
SV_SendPlayerInfo(node); // Send extra info
|
||||||
|
}
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
}
|
30
src/netcode/server_connection.h
Normal file
30
src/netcode/server_connection.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file server_connection.h
|
||||||
|
/// \brief Server-side part of connection handling
|
||||||
|
|
||||||
|
#ifndef __D_SERVER_CONNECTION__
|
||||||
|
#define __D_SERVER_CONNECTION__
|
||||||
|
|
||||||
|
#include "../command.h"
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
void PT_ClientJoin(SINT8 node);
|
||||||
|
void PT_AskInfoViaMS(SINT8 node);
|
||||||
|
void PT_TellFilesNeeded(SINT8 node);
|
||||||
|
void PT_AskInfo(SINT8 node);
|
||||||
|
|
||||||
|
extern tic_t jointimeout;
|
||||||
|
extern tic_t joindelay;
|
||||||
|
extern char playeraddress[MAXPLAYERS][64];
|
||||||
|
extern consvar_t cv_showjoinaddress, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout;
|
||||||
|
|
||||||
|
#endif
|
471
src/netcode/tic_command.c
Normal file
471
src/netcode/tic_command.c
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file tic_command.c
|
||||||
|
/// \brief Tic command handling
|
||||||
|
|
||||||
|
#include "tic_command.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "net_command.h"
|
||||||
|
#include "client_connection.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "../d_main.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../i_system.h"
|
||||||
|
#include "../i_time.h"
|
||||||
|
#include "../byteptr.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
tic_t firstticstosend; // Smallest netnode.tic
|
||||||
|
tic_t tictoclear = 0; // Optimize D_ClearTiccmd
|
||||||
|
ticcmd_t localcmds;
|
||||||
|
ticcmd_t localcmds2;
|
||||||
|
boolean cl_packetmissed;
|
||||||
|
ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||||
|
|
||||||
|
static inline void *G_DcpyTiccmd(void* dest, const ticcmd_t* src, const size_t n)
|
||||||
|
{
|
||||||
|
const size_t d = n / sizeof(ticcmd_t);
|
||||||
|
const size_t r = n % sizeof(ticcmd_t);
|
||||||
|
UINT8 *ret = dest;
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
M_Memcpy(dest, src, n);
|
||||||
|
else if (d)
|
||||||
|
G_MoveTiccmd(dest, src, d);
|
||||||
|
return ret+n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n)
|
||||||
|
{
|
||||||
|
const size_t d = n / sizeof(ticcmd_t);
|
||||||
|
const size_t r = n % sizeof(ticcmd_t);
|
||||||
|
UINT8 *ret = src;
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
M_Memcpy(dest, src, n);
|
||||||
|
else if (d)
|
||||||
|
G_MoveTiccmd(dest, src, d);
|
||||||
|
return ret+n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Guesses the full value of a tic from its lowest byte, for a specific node
|
||||||
|
*
|
||||||
|
* \param low The lowest byte of the tic value
|
||||||
|
* \param node The node to deduce the tic for
|
||||||
|
* \return The full tic value
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
tic_t ExpandTics(INT32 low, INT32 node)
|
||||||
|
{
|
||||||
|
INT32 delta;
|
||||||
|
|
||||||
|
delta = low - (netnodes[node].tic & UINT8_MAX);
|
||||||
|
|
||||||
|
if (delta >= -64 && delta <= 64)
|
||||||
|
return (netnodes[node].tic & ~UINT8_MAX) + low;
|
||||||
|
else if (delta > 64)
|
||||||
|
return (netnodes[node].tic & ~UINT8_MAX) - 256 + low;
|
||||||
|
else //if (delta < -64)
|
||||||
|
return (netnodes[node].tic & ~UINT8_MAX) + 256 + low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D_Clearticcmd(tic_t tic)
|
||||||
|
{
|
||||||
|
D_FreeTextcmd(tic);
|
||||||
|
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
netcmds[tic%BACKUPTICS][i].angleturn = 0;
|
||||||
|
|
||||||
|
DEBFILE(va("clear tic %5u (%2u)\n", tic, tic%BACKUPTICS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void D_ResetTiccmds(void)
|
||||||
|
{
|
||||||
|
memset(&localcmds, 0, sizeof(ticcmd_t));
|
||||||
|
memset(&localcmds2, 0, sizeof(ticcmd_t));
|
||||||
|
|
||||||
|
// Reset the net command list
|
||||||
|
for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++)
|
||||||
|
while (textcmds[i])
|
||||||
|
D_Clearticcmd(textcmds[i]->tic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ticcmd for "speed hacks"
|
||||||
|
static void CheckTiccmdHacks(INT32 playernum, tic_t tic)
|
||||||
|
{
|
||||||
|
ticcmd_t *cmd = &netcmds[tic%BACKUPTICS][playernum];
|
||||||
|
if (cmd->forwardmove > MAXPLMOVE || cmd->forwardmove < -MAXPLMOVE
|
||||||
|
|| cmd->sidemove > MAXPLMOVE || cmd->sidemove < -MAXPLMOVE)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernum);
|
||||||
|
SendKick(playernum, KICK_MSG_CON_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check player consistancy during the level
|
||||||
|
static void CheckConsistancy(SINT8 nodenum, tic_t tic)
|
||||||
|
{
|
||||||
|
netnode_t *node = &netnodes[nodenum];
|
||||||
|
INT16 neededconsistancy = consistancy[tic%BACKUPTICS];
|
||||||
|
INT16 clientconsistancy = SHORT(netbuffer->u.clientpak.consistancy);
|
||||||
|
|
||||||
|
if (tic > gametic || tic + BACKUPTICS - 1 <= gametic || gamestate != GS_LEVEL
|
||||||
|
|| neededconsistancy == clientconsistancy || SV_ResendingSavegameToAnyone()
|
||||||
|
|| node->resendingsavegame || node->savegameresendcooldown > I_GetTime())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cv_resynchattempts.value)
|
||||||
|
{
|
||||||
|
// Tell the client we are about to resend them the gamestate
|
||||||
|
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||||
|
HSendPacket(nodenum, true, 0, 0);
|
||||||
|
|
||||||
|
node->resendingsavegame = true;
|
||||||
|
|
||||||
|
if (cv_blamecfail.value)
|
||||||
|
CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"),
|
||||||
|
node->player+1, player_names[node->player],
|
||||||
|
neededconsistancy, clientconsistancy);
|
||||||
|
|
||||||
|
DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n",
|
||||||
|
node->player, tic, neededconsistancy, clientconsistancy));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendKick(node->player, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
|
||||||
|
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
||||||
|
node->player, tic, neededconsistancy, clientconsistancy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_ClientCmd(SINT8 nodenum, INT32 netconsole)
|
||||||
|
{
|
||||||
|
netnode_t *node = &netnodes[nodenum];
|
||||||
|
tic_t realend, realstart;
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// To save bytes, only the low byte of tic numbers are sent
|
||||||
|
// Use ExpandTics to figure out what the rest of the bytes are
|
||||||
|
realstart = ExpandTics(netbuffer->u.clientpak.client_tic, nodenum);
|
||||||
|
realend = ExpandTics(netbuffer->u.clientpak.resendfrom, nodenum);
|
||||||
|
|
||||||
|
if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS
|
||||||
|
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS
|
||||||
|
|| node->supposedtic < realend)
|
||||||
|
{
|
||||||
|
node->supposedtic = realend;
|
||||||
|
}
|
||||||
|
// Discard out of order packet
|
||||||
|
if (node->tic > realend)
|
||||||
|
{
|
||||||
|
DEBFILE(va("out of order ticcmd discarded nettics = %u\n", node->tic));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the nettics
|
||||||
|
node->tic = realend;
|
||||||
|
|
||||||
|
// This should probably still timeout though, as the node should always have a player 1 number
|
||||||
|
if (netconsole == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||||
|
/// \todo Use a separate cvar for that kind of timeout?
|
||||||
|
node->freezetimeout = I_GetTime() + connectiontimeout;
|
||||||
|
|
||||||
|
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||||
|
// Sryder 2018/07/01: Update the freezetimeout still!
|
||||||
|
if (netbuffer->packettype == PT_NODEKEEPALIVE
|
||||||
|
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
|
||||||
|
tic_t faketic = maketic;
|
||||||
|
if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED))
|
||||||
|
&& (maketic - firstticstosend < BACKUPTICS - 1))
|
||||||
|
faketic++;
|
||||||
|
|
||||||
|
// Copy ticcmd
|
||||||
|
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||||
|
|
||||||
|
// Splitscreen cmd
|
||||||
|
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||||
|
&& node->player2 >= 0)
|
||||||
|
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][(UINT8)node->player2],
|
||||||
|
&netbuffer->u.client2pak.cmd2, 1);
|
||||||
|
|
||||||
|
CheckTiccmdHacks(netconsole, faketic);
|
||||||
|
CheckConsistancy(nodenum, realstart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||||
|
{
|
||||||
|
tic_t realend, realstart;
|
||||||
|
servertics_pak *packet = &netbuffer->u.serverpak;
|
||||||
|
|
||||||
|
if (!netnodes[node].ingame)
|
||||||
|
{
|
||||||
|
// Do not remove my own server (we have just get a out of order packet)
|
||||||
|
if (node != servernode)
|
||||||
|
{
|
||||||
|
DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype));
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only accept PT_SERVERTICS from the server.
|
||||||
|
if (node != servernode)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
|
||||||
|
if (server)
|
||||||
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
realstart = packet->starttic;
|
||||||
|
realend = realstart + packet->numtics;
|
||||||
|
|
||||||
|
realend = min(realend, gametic + CLIENTBACKUPTICS);
|
||||||
|
cl_packetmissed = realstart > neededtic;
|
||||||
|
|
||||||
|
if (realstart <= neededtic && realend > neededtic)
|
||||||
|
{
|
||||||
|
UINT8 *pak = (UINT8 *)&packet->cmds;
|
||||||
|
UINT8 *txtpak = (UINT8 *)&packet->cmds[packet->numslots * packet->numtics];
|
||||||
|
|
||||||
|
for (tic_t i = realstart; i < realend; i++)
|
||||||
|
{
|
||||||
|
// clear first
|
||||||
|
D_Clearticcmd(i);
|
||||||
|
|
||||||
|
// copy the tics
|
||||||
|
pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak,
|
||||||
|
packet->numslots*sizeof (ticcmd_t));
|
||||||
|
|
||||||
|
CL_CopyNetCommandsFromServerPacket(i, &txtpak);
|
||||||
|
}
|
||||||
|
|
||||||
|
neededtic = realend;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBFILE(va("frame not in bound: %u\n", neededtic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the client packet to the server
|
||||||
|
void CL_SendClientCmd(void)
|
||||||
|
{
|
||||||
|
size_t packetsize = 0;
|
||||||
|
boolean mis = false;
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_CLIENTCMD;
|
||||||
|
|
||||||
|
if (cl_packetmissed)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_CLIENTMIS;
|
||||||
|
mis = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX);
|
||||||
|
netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX);
|
||||||
|
|
||||||
|
if (gamestate == GS_WAITINGPLAYERS)
|
||||||
|
{
|
||||||
|
// Send PT_NODEKEEPALIVE packet
|
||||||
|
netbuffer->packettype = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE);
|
||||||
|
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||||
|
HSendPacket(servernode, false, 0, packetsize);
|
||||||
|
}
|
||||||
|
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||||
|
{
|
||||||
|
packetsize = sizeof (clientcmd_pak);
|
||||||
|
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||||
|
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||||
|
|
||||||
|
// Send a special packet with 2 cmd for splitscreen
|
||||||
|
if (splitscreen || botingame)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
|
||||||
|
packetsize = sizeof (client2cmd_pak);
|
||||||
|
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
HSendPacket(servernode, false, 0, packetsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cl_mode == CL_CONNECTED || dedicated)
|
||||||
|
CL_SendNetCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PT_SERVERTICS packets can grow too large for a single UDP packet,
|
||||||
|
// So this checks how many tics worth of data can be sent in one packet.
|
||||||
|
// The rest can be sent later, usually the next tic.
|
||||||
|
static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t lasttic)
|
||||||
|
{
|
||||||
|
size_t size = BASESERVERTICSSIZE;
|
||||||
|
|
||||||
|
for (tic_t tic = firsttic; tic < lasttic; tic++)
|
||||||
|
{
|
||||||
|
size += sizeof (ticcmd_t) * doomcom->numslots;
|
||||||
|
size += TotalTextCmdPerTic(tic);
|
||||||
|
|
||||||
|
if (size > software_MAXPACKETLENGTH)
|
||||||
|
{
|
||||||
|
DEBFILE(va("packet too large (%s) at tic %d (should be from %d to %d)\n",
|
||||||
|
sizeu1(size), tic, firsttic, lasttic));
|
||||||
|
lasttic = tic;
|
||||||
|
|
||||||
|
// Too bad: too many players have sent extra data
|
||||||
|
// and there is too much data for a single tic.
|
||||||
|
// To avoid that, keep the data for the next tic (see PT_TEXTCMD).
|
||||||
|
if (lasttic == firsttic)
|
||||||
|
{
|
||||||
|
if (size > MAXPACKETLENGTH)
|
||||||
|
I_Error("Too many players: can't send %s data for %d players to node %d\n"
|
||||||
|
"Well sorry nobody is perfect....\n",
|
||||||
|
sizeu1(size), doomcom->numslots, nodenum);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lasttic++; // send it anyway!
|
||||||
|
DEBFILE("sending it anyway\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lasttic - firsttic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends the server packet
|
||||||
|
// Sends tic/net commands from firstticstosend to maketic-1
|
||||||
|
void SV_SendTics(void)
|
||||||
|
{
|
||||||
|
tic_t realfirsttic, lasttictosend;
|
||||||
|
|
||||||
|
// Send to all clients except yourself
|
||||||
|
// For each node, create a packet with x tics and send it
|
||||||
|
// x is computed using node.supposedtic, max packet size and maketic
|
||||||
|
for (INT32 n = 1; n < MAXNETNODES; n++)
|
||||||
|
if (netnodes[n].ingame)
|
||||||
|
{
|
||||||
|
netnode_t *node = &netnodes[n];
|
||||||
|
|
||||||
|
// assert node->supposedtic>=node->tic
|
||||||
|
realfirsttic = node->supposedtic;
|
||||||
|
lasttictosend = min(maketic, node->tic + CLIENTBACKUPTICS);
|
||||||
|
|
||||||
|
if (realfirsttic >= lasttictosend)
|
||||||
|
{
|
||||||
|
// Well, we have sent all the tics, so we will use extra bandwidth
|
||||||
|
// to resend packets that are supposed lost.
|
||||||
|
// This is necessary since lost packet detection
|
||||||
|
// works when we receive a packet with firsttic > neededtic (PT_SERVERTICS)
|
||||||
|
DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n",
|
||||||
|
n, maketic, node->supposedtic, node->tic));
|
||||||
|
|
||||||
|
realfirsttic = node->tic;
|
||||||
|
|
||||||
|
if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3)
|
||||||
|
// All tics are Ok
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DEBFILE(va("Sent %d anyway\n", realfirsttic));
|
||||||
|
}
|
||||||
|
realfirsttic = max(realfirsttic, firstticstosend);
|
||||||
|
|
||||||
|
lasttictosend = realfirsttic + SV_CalculateNumTicsForPacket(n, realfirsttic, lasttictosend);
|
||||||
|
|
||||||
|
// Prepare the packet header
|
||||||
|
netbuffer->packettype = PT_SERVERTICS;
|
||||||
|
netbuffer->u.serverpak.starttic = realfirsttic;
|
||||||
|
netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic);
|
||||||
|
netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots);
|
||||||
|
|
||||||
|
// Fill and send the packet
|
||||||
|
UINT8 *bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds;
|
||||||
|
for (tic_t i = realfirsttic; i < lasttictosend; i++)
|
||||||
|
bufpos = G_DcpyTiccmd(bufpos, netcmds[i%BACKUPTICS], doomcom->numslots * sizeof (ticcmd_t));
|
||||||
|
for (tic_t i = realfirsttic; i < lasttictosend; i++)
|
||||||
|
SV_WriteNetCommandsForTic(i, &bufpos);
|
||||||
|
size_t packsize = bufpos - (UINT8 *)&(netbuffer->u);
|
||||||
|
HSendPacket(n, false, 0, packsize);
|
||||||
|
|
||||||
|
// When tics are too large, only one tic is sent so don't go backwards!
|
||||||
|
if (lasttictosend-doomcom->extratics > realfirsttic)
|
||||||
|
node->supposedtic = lasttictosend-doomcom->extratics;
|
||||||
|
else
|
||||||
|
node->supposedtic = lasttictosend;
|
||||||
|
node->supposedtic = max(node->supposedtic, node->tic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// node 0 is me!
|
||||||
|
netnodes[0].supposedtic = maketic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Local_Maketic(INT32 realtics)
|
||||||
|
{
|
||||||
|
I_OsPolling(); // I_Getevent
|
||||||
|
D_ProcessEvents(); // menu responder, cons responder,
|
||||||
|
// game responder calls HU_Responder, AM_Responder,
|
||||||
|
// and G_MapEventsToControls
|
||||||
|
if (!dedicated)
|
||||||
|
rendergametic = gametic;
|
||||||
|
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||||
|
G_BuildTiccmd(&localcmds, realtics, 1);
|
||||||
|
if (splitscreen || botingame)
|
||||||
|
G_BuildTiccmd(&localcmds2, realtics, 2);
|
||||||
|
|
||||||
|
localcmds.angleturn |= TICCMD_RECEIVED;
|
||||||
|
localcmds2.angleturn |= TICCMD_RECEIVED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create missed tic
|
||||||
|
void SV_Maketic(void)
|
||||||
|
{
|
||||||
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We didn't receive this tic
|
||||||
|
if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0)
|
||||||
|
{
|
||||||
|
ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i];
|
||||||
|
ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i];
|
||||||
|
|
||||||
|
if (players[i].quittime)
|
||||||
|
{
|
||||||
|
// Copy the angle/aiming from the previous tic
|
||||||
|
// and empty the other inputs
|
||||||
|
memset(ticcmd, 0, sizeof(netcmds[0][0]));
|
||||||
|
ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED;
|
||||||
|
ticcmd->aiming = prevticcmd->aiming;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBFILE(va("MISS tic%4d for player %d\n", maketic, i));
|
||||||
|
// Copy the input from the previous tic
|
||||||
|
*ticcmd = *prevticcmd;
|
||||||
|
ticcmd->angleturn &= ~TICCMD_RECEIVED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All tics have been processed, make the next
|
||||||
|
maketic++;
|
||||||
|
}
|
44
src/netcode/tic_command.h
Normal file
44
src/netcode/tic_command.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file tic_command.h
|
||||||
|
/// \brief Tic command handling
|
||||||
|
|
||||||
|
#ifndef __D_TIC_COMMAND__
|
||||||
|
#define __D_TIC_COMMAND__
|
||||||
|
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "../d_ticcmd.h"
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
extern tic_t firstticstosend; // min of the nettics
|
||||||
|
extern tic_t tictoclear; // optimize d_clearticcmd
|
||||||
|
|
||||||
|
extern ticcmd_t localcmds;
|
||||||
|
extern ticcmd_t localcmds2;
|
||||||
|
extern boolean cl_packetmissed;
|
||||||
|
|
||||||
|
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||||
|
|
||||||
|
tic_t ExpandTics(INT32 low, INT32 node);
|
||||||
|
void D_Clearticcmd(tic_t tic);
|
||||||
|
void D_ResetTiccmds(void);
|
||||||
|
|
||||||
|
void PT_ClientCmd(SINT8 nodenum, INT32 netconsole);
|
||||||
|
void PT_ServerTics(SINT8 node, INT32 netconsole);
|
||||||
|
|
||||||
|
// send the client packet to the server
|
||||||
|
void CL_SendClientCmd(void);
|
||||||
|
|
||||||
|
void SV_SendTics(void);
|
||||||
|
void Local_Maketic(INT32 realtics);
|
||||||
|
void SV_Maketic(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,7 +17,7 @@
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// CEILINGS
|
// CEILINGS
|
||||||
|
|
|
@ -5248,7 +5248,7 @@ void A_SignPlayer(mobj_t *actor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
skin = &skins[actor->target->player->skin];
|
skin = &skins[actor->target->player->skin];
|
||||||
facecolor = actor->target->player->skincolor;
|
facecolor = P_GetPlayerColor(actor->target->player);
|
||||||
|
|
||||||
if (signcolor)
|
if (signcolor)
|
||||||
;
|
;
|
||||||
|
@ -9059,7 +9059,7 @@ void A_Dye(mobj_t *actor)
|
||||||
if (!color)
|
if (!color)
|
||||||
{
|
{
|
||||||
target->colorized = false;
|
target->colorized = false;
|
||||||
target->color = target->player ? target->player->skincolor : SKINCOLOR_NONE;
|
target->color = target->player ? P_GetPlayerColor(target->player) : SKINCOLOR_NONE;
|
||||||
}
|
}
|
||||||
else if (!(target->player))
|
else if (!(target->player))
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "v_video.h" // video flags for CEchos
|
#include "v_video.h" // video flags for CEchos
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "netcode/net_command.h"
|
||||||
|
|
||||||
// CTF player names
|
// CTF player names
|
||||||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
||||||
|
@ -1144,7 +1145,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
if (!(mo2->type == MT_RING || mo2->type == MT_COIN
|
if (!(mo2->type == MT_RING || mo2->type == MT_COIN
|
||||||
|| mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE
|
|| mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE
|
||||||
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR
|
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR
|
||||||
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL))))
|
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL) && P_CanPickupEmblem(player, mo2->health - 1) && !P_EmblemWasCollected(mo2->health - 1))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Yay! The thing's in reach! Pull it in!
|
// Yay! The thing's in reach! Pull it in!
|
||||||
|
@ -2235,7 +2236,7 @@ void P_CheckTimeLimit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Optional tie-breaker for Match/CTF
|
//Optional tie-breaker for Match/CTF
|
||||||
|
@ -2298,11 +2299,11 @@ void P_CheckTimeLimit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if a player's score is over the pointlimit and the round should end.
|
/** Checks if a player's score is over the pointlimit and the round should end.
|
||||||
|
@ -2331,7 +2332,7 @@ void P_CheckPointLimit(void)
|
||||||
if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore)
|
if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2344,7 +2345,7 @@ void P_CheckPointLimit(void)
|
||||||
if ((UINT32)cv_pointlimit.value <= players[i].score)
|
if ((UINT32)cv_pointlimit.value <= players[i].score)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2388,7 +2389,7 @@ void P_CheckSurvivors(void)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("The IT player has left the game.\n"));
|
CONS_Printf(M_GetText("The IT player has left the game.\n"));
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2408,7 +2409,7 @@ void P_CheckSurvivors(void)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2420,7 +2421,7 @@ void P_CheckSurvivors(void)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("There are no players able to become IT.\n"));
|
CONS_Printf(M_GetText("There are no players able to become IT.\n"));
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2432,7 +2433,7 @@ void P_CheckSurvivors(void)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||||
if (server)
|
if (server)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
D_SendExitLevel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2630,7 +2631,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target->color = target->player->skincolor;
|
target->color = P_GetPlayerColor(target->player);
|
||||||
target->colorized = false;
|
target->colorized = false;
|
||||||
G_GhostAddColor(GHC_NORMAL);
|
G_GhostAddColor(GHC_NORMAL);
|
||||||
|
|
||||||
|
@ -3323,7 +3324,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||||
|
|
||||||
// Get rid of shield
|
// Get rid of shield
|
||||||
player->powers[pw_shield] = SH_NONE;
|
player->powers[pw_shield] = SH_NONE;
|
||||||
player->mo->color = player->skincolor;
|
player->mo->color = P_GetPlayerColor(player);
|
||||||
|
|
||||||
// Get rid of emeralds
|
// Get rid of emeralds
|
||||||
player->powers[pw_emeralds] = 0;
|
player->powers[pw_emeralds] = 0;
|
||||||
|
@ -3440,7 +3441,7 @@ void P_RemoveShield(player_t *player)
|
||||||
{ // Second layer shields
|
{ // Second layer shields
|
||||||
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability])))
|
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability])))
|
||||||
{
|
{
|
||||||
player->mo->color = player->skincolor;
|
player->mo->color = P_GetPlayerColor(player);
|
||||||
G_GhostAddColor(GHC_NORMAL);
|
G_GhostAddColor(GHC_NORMAL);
|
||||||
}
|
}
|
||||||
player->powers[pw_shield] = SH_NONE;
|
player->powers[pw_shield] = SH_NONE;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "d_netcmd.h"
|
#include "netcode/d_netcmd.h"
|
||||||
|
|
||||||
/** Removes any active lighting effects in a sector.
|
/** Removes any active lighting effects in a sector.
|
||||||
*
|
*
|
||||||
|
|
|
@ -146,6 +146,7 @@ void P_ForceLocalAngle(player_t *player, angle_t angle);
|
||||||
boolean P_PlayerFullbright(player_t *player);
|
boolean P_PlayerFullbright(player_t *player);
|
||||||
boolean P_PlayerCanEnterSpinGaps(player_t *player);
|
boolean P_PlayerCanEnterSpinGaps(player_t *player);
|
||||||
boolean P_PlayerShouldUseSpinHeight(player_t *player);
|
boolean P_PlayerShouldUseSpinHeight(player_t *player);
|
||||||
|
UINT16 P_GetPlayerColor(player_t *player);
|
||||||
|
|
||||||
boolean P_IsObjectInGoop(mobj_t *mo);
|
boolean P_IsObjectInGoop(mobj_t *mo);
|
||||||
boolean P_IsObjectOnGround(mobj_t *mo);
|
boolean P_IsObjectOnGround(mobj_t *mo);
|
||||||
|
|
11
src/p_map.c
11
src/p_map.c
|
@ -2524,7 +2524,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
{
|
{
|
||||||
subsector_t *s = R_PointInSubsector(x, y);
|
subsector_t *s = R_PointInSubsector(x, y);
|
||||||
boolean retval = true;
|
|
||||||
boolean itsatwodlevel = false;
|
boolean itsatwodlevel = false;
|
||||||
|
|
||||||
floatok = false;
|
floatok = false;
|
||||||
|
@ -2539,8 +2538,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
fixed_t tryx = thiscam->x;
|
fixed_t tryx = thiscam->x;
|
||||||
fixed_t tryy = thiscam->y;
|
fixed_t tryy = thiscam->y;
|
||||||
|
|
||||||
if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP))
|
if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP || players[displayplayer].powers[pw_carry] == CR_NIGHTSMODE))
|
||||||
|| (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP)))
|
|| (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP || players[secondarydisplayplayer].powers[pw_carry] == CR_NIGHTSMODE)))
|
||||||
{ // Noclipping player camera noclips too!!
|
{ // Noclipping player camera noclips too!!
|
||||||
floatok = true;
|
floatok = true;
|
||||||
thiscam->floorz = thiscam->z;
|
thiscam->floorz = thiscam->z;
|
||||||
|
@ -2608,7 +2607,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
thiscam->y = y;
|
thiscam->y = y;
|
||||||
thiscam->subsector = s;
|
thiscam->subsector = s;
|
||||||
|
|
||||||
return retval;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3731,7 +3730,9 @@ void P_SlideMove(mobj_t *mo)
|
||||||
|
|
||||||
boolean papercol = false;
|
boolean papercol = false;
|
||||||
vertex_t v1, v2; // fake vertexes
|
vertex_t v1, v2; // fake vertexes
|
||||||
line_t junk; // fake linedef
|
static line_t junk; // fake linedef
|
||||||
|
|
||||||
|
memset(&junk, 0x00, sizeof(junk));
|
||||||
|
|
||||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||||
{
|
{
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue