Merge branch 'mapbase-source:develop' into develop

This commit is contained in:
Crimson-X1 2022-12-27 19:06:16 -08:00 committed by GitHub
commit 783c8e8fb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 5577 additions and 397 deletions

View File

@ -23,31 +23,40 @@ All contributions must follow the following rules:
is usually not fit for Mapbase. is usually not fit for Mapbase.
* All content in a contribution must be either already legally open-source or done with the * All content in a contribution must be either already legally open-source or done with the
full permission of the content's original creator(s). If licensing is involved, the contribution full permission of the content's original creator(s). If a license is involved, the contributor
must ensure Mapbase follows said licensing. should ensure Mapbase conforms to its terms.
* **NOTE:** Due to concerns with mods which do not wish to be open-source, content using GPL licenses (or any * **NOTE:** Due to concerns with mods which do not wish to be open-source, content using GPL licenses (or any
license with similar open-source requirements) are currently not allowed to be distributed with Mapbase. license with similar open-source requirements) are currently not allowed to be distributed with Mapbase.
Contributions which can draw from them without actually distributing the licensed content may theoretically Contributions which can draw from them without actually distributing the licensed content may be excepted
be excepted from this rule. from this rule.
* Contributions must not break existing maps/content or interfere with them in a negative or non-objective way. * Contributions must not break existing maps/content or interfere with them in a negative or non-objective way.
* Code contributions are not obliged to follow Mapbase's preprocessor conventions (e.g. #ifdef MAPBASE), * Code contributions are not obliged to follow Mapbase's preprocessor conventions (e.g. #ifdef MAPBASE),
although following them is usually acceptable. although following them is usually acceptable.
* Code contributions which modify or add onto existing code should generally match its syntax and shouldn't
change the spacing unless necessary.
* If you are contributing a file you created yourself specifically for Mapbase, you are required to * If you are contributing a file you created yourself specifically for Mapbase, you are required to
use the custom "Mapbase - Source 2013" header used in other Mapbase files as of Mapbase v5.0. use the custom "Mapbase - Source 2013" header used in other Mapbase files as of Mapbase v5.0.
You are encouraged to append an "Author(s)" part to that header in your file in order to clarify who wrote it. You are encouraged to append an "Author(s)" part to that header in your file in order to clarify who wrote it.
* Do not modify the README to add attribution for your contribution. That is handled by Mapbase's maintainers. * Do not modify the README to add attribution for your contribution. That is handled by Mapbase's maintainers.
Contributions which do not follow these guidelines cannot be accepted into Mapbase. Contributions which do not follow these guidelines cannot be accepted into Mapbase. Attempting to contribute content
which seriously violates the rules above can lead to being blocked from contributing, especially if done repeatedly.
Attempting to contribute content which seriously violates the rules above can lead to being blocked from contributing,
especially if done repeatedly.
--- ---
Mapbase uses GitHub Actions to help manage issues and pull requests. Some of these workflows build the code of incoming
contributions to make sure they compile properly. The code is compiled separately for Visual Studio 2022 and GCC/G++ 9 (Linux)
and on both Debug and Release configurations.
If these workflows fail, don't freak out! Accidents can happen frequently due to compiler syntax differences and conflicts
from other contributions. You can look at a failed workflow's log by clicking "Details", which will include the build's output
in the "Build" step(s). Any errors must be resolved by you and/or by code reviewers before a pull request can be merged.
If your contribution is accepted, you may be listed in Mapbase's credits and the README's external content list: If your contribution is accepted, you may be listed in Mapbase's credits and the README's external content list:
https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits#Contributors https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits#Contributors
https://github.com/mapbase-source/source-sdk-2013/blob/master/README https://github.com/mapbase-source/source-sdk-2013/blob/master/README

35
.github/labeler.yml vendored Normal file
View File

@ -0,0 +1,35 @@
#
# MAPBASE REPO AUTOMATION
#
# Automatically labels pull requests according to changed file paths.
# See mapbase_pr.yml for more information.
#
Repo:
- '*'
- '.github/**'
Project Generation:
- '**/src/vpc_scripts/**'
- '**/src/devtools/**'
- '**/src/create*'
Entities:
- '**/src/game/**/**logic**'
- '**/src/game/**/**point**'
Shaders:
- '**/src/materialsystem/**'
VScript:
- '**vscript**'
Tools:
- '**utils**'
NPCs:
- '**npc_**'
- '**ai_**'
VGUI:
- '**hud_**'
- '**vgui_**'

View File

@ -0,0 +1,70 @@
#
# MAPBASE SOURCE 2013 CI
#
# This can be used to manually build the codebase.
#
# See mapbase_build-base.yml for more information on how this works.
name: Build Projects (Manual)
on:
workflow_dispatch:
inputs:
configuration:
description: 'Which configuration to build with'
default: 'Release'
required: true
type: choice
options:
- Release
- Debug
branch:
description: 'Which Source 2013 engine branch to compile for'
default: 'sp'
required: true
type: choice
options:
- sp
- mp
game:
description: 'Name of the game to build (if relevant)'
default: 'episodic'
required: false
type: choice
options:
- episodic
- hl2
project-group:
description: 'Which group of projects to compile'
required: true
type: choice
options:
- all
- game
- shaders
- maptools
solution-name:
description: 'Name of the solution/makefile'
required: true
type: choice
options:
- everything
- games
- shaders
- maptools
build-on-linux:
description: 'Build on Ubuntu/Linux?'
default: true
required: false
type: boolean
jobs:
build_manual:
uses: ./.github/workflows/mapbase_build-base.yml
with:
configuration: '${{ github.event.inputs.configuration }}'
branch: '${{ github.event.inputs.branch }}'
game: '${{ github.event.inputs.game }}'
project-group: '${{ github.event.inputs.project-group }}'
solution-name: '${{ github.event.inputs.solution-name }}'
build-on-linux: "${{ github.event.inputs.build-on-linux == 'true' }}"

269
.github/workflows/mapbase_build-base.yml vendored Normal file
View File

@ -0,0 +1,269 @@
#
# MAPBASE SOURCE 2013 CI
#
# This workflow script automatically builds the Source SDK 2013 codebase on Windows and Linux using GitHub Actions.
#
# This is useful in a number of ways:
#
# 1. It ensures pull requests compile correctly on multiple platforms and provides binaries that can be used to test them.
# 2. It can be used to compile code for releases without having to pull and prepare a local development environment.
# 3. It opens potential for scripts that can employ more principles of CI/CD. (e.g. automatically publishing a release)
#
# This is based on a workflow originally created by z33ky.
name: Build Projects
on:
workflow_call:
inputs:
configuration:
description: 'Which configuration to build with'
default: 'Release'
required: true
type: string
branch:
description: 'Which Source 2013 engine branch to compile for'
default: 'sp'
required: true
type: string
game:
description: 'The name of the game to build (if relevant)'
default: 'episodic'
required: false
type: string
project-group:
description: 'Which group of projects to compile'
required: true
type: string
solution-name:
description: 'The name of the solution/makefile'
required: true
type: string
build-on-linux:
description: 'Build on Ubuntu/Linux?'
default: true
required: false
type: boolean
jobs:
build_windows:
name: Windows (VS2022)
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.1
- name: Enable VS2022
working-directory: '${{inputs.branch}}/src/vpc_scripts'
shell: bash
run: sed -i 's/^\($Conditional[ ]\+VS2022[ ]\+\).*/\1"1"/' newer_vs_toolsets.vpc
- name: Pick game
if: inputs.project-group == 'game' || inputs.project-group == 'shaders'
working-directory: '${{inputs.branch}}/src'
shell: bash
run: sed -i 's/\/hl2 \/episodic/\/${{inputs.game}}/' create${{inputs.project-group}}projects.bat
- name: Create project files
working-directory: '${{inputs.branch}}/src'
shell: cmd
# https://github.com/ValveSoftware/source-sdk-2013/issues/72
run: |
reg add "HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\10.0\Projects\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}" /v DefaultProjectExtension /t REG_SZ /d vcproj /f
create${{inputs.project-group}}projects.bat
# --------------------------------------------------------------------
# "I'm invoking msbuild for each project individually, which looks a bit odd considering there is a solution file which should be able to invoke the builds in their proper order automatically, but passing the solution to msbuild doesn't seem to work."
# https://github.com/mapbase-source/source-sdk-2013/pull/162
- name: Build mathlib
#if: steps.filter.outputs.game == 'true'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} mathlib\mathlib.vcxproj
- name: Build Base Libraries
if: inputs.project-group == 'all' || inputs.project-group == 'game' || inputs.project-group == 'maptools'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} raytrace\raytrace.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} tier1\tier1.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} vgui2\vgui_controls\vgui_controls.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} vscript\vscript.vcxproj
- name: Build Map Tools
if: inputs.project-group == 'all' || inputs.project-group == 'maptools'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} fgdlib\fgdlib.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vbsp\vbsp.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vvis\vvis_dll.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vvis_launcher\vvis_launcher.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vrad\vrad_dll.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vrad_launcher\vrad_launcher.vcxproj
- name: Build Shaders
if: inputs.project-group == 'shaders'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_${{inputs.game}}.vcxproj
- name: Build Game
if: inputs.project-group == 'game'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} responserules\runtime\responserules.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_${{inputs.game}}.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_${{inputs.game}}.vcxproj
# TODO: Hook to game naming?
- name: Build everything
if: inputs.project-group == 'all'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} responserules\runtime\responserules.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_hl2.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_hl2.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_hl2.vcxproj
# --------------------------------------------------------------------
- name: Publish Windows game DLLs
if: inputs.project-group == 'game'
uses: actions/upload-artifact@v3
with:
name: 'Windows Game DLLs (server & client.dll) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/client.dll
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/server.dll
if-no-files-found: error
- name: Publish Windows shader DLL
if: inputs.project-group == 'shaders'
uses: actions/upload-artifact@v3
with:
name: 'Windows Shader DLL (game_shader_dx9.dll) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/game_shader_dx9.dll
if-no-files-found: error
- name: Publish Windows map tools
if: inputs.project-group == 'maptools'
uses: actions/upload-artifact@v3
with:
name: 'Windows Map Tools [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/bin/vbsp.exe
${{inputs.branch}}/game/bin/vvis.exe
${{inputs.branch}}/game/bin/vvis_dll.dll
${{inputs.branch}}/game/bin/vrad.exe
${{inputs.branch}}/game/bin/vrad_dll.dll
if-no-files-found: error
- name: Publish everything (Windows)
if: inputs.project-group == 'all'
uses: actions/upload-artifact@v3
with:
name: 'Everything (Windows) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/bin
${{inputs.branch}}/game/mod_*/bin
if-no-files-found: error
build_ubuntu:
if: inputs.build-on-linux == true && inputs.project-group != 'maptools' # No Linux map tools for now
name: Ubuntu (GCC/G++)
runs-on: ubuntu-latest
env:
config: ${{ inputs.configuration }}
steps:
- uses: actions/checkout@v3
- name: Install GCC/G++ multilib
run: sudo apt-get install gcc-multilib g++-multilib
- name: Pick game
if: inputs.project-group == 'game' || inputs.project-group == 'shaders'
working-directory: '${{inputs.branch}}/src'
shell: bash
run: sed -i 's/\/hl2 \/episodic/\/${{inputs.game}}/' create${{inputs.project-group}}projects
- name: Set configuration
working-directory: '${{inputs.branch}}/src'
shell: bash
run: |
config=${{inputs.configuration}}
export CFG=${config,,}
echo "config=${CFG}" >> $GITHUB_ENV
- name: Create project files
working-directory: '${{inputs.branch}}/src'
run: ./create${{inputs.project-group}}projects
# --------------------------------------------------------------------
- name: Build
working-directory: '${{inputs.branch}}/src'
run: make CFG=${{env.config}} -f ${{inputs.solution-name}}.mak
# --------------------------------------------------------------------
- name: Publish Linux game SOs
if: inputs.project-group == 'game'
uses: actions/upload-artifact@v3
with:
name: 'Linux Game SOs (server & client.so) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/client.so
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/server.so
if-no-files-found: error
- name: Publish Linux shader SO
if: inputs.project-group == 'shaders'
uses: actions/upload-artifact@v3
with:
name: 'Linux Shader SO (game_shader_dx9.so) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/game_shader_dx9.so
if-no-files-found: error
#- name: Publish Linux map tools
# if: inputs.project-group == 'maptools'
# uses: actions/upload-artifact@v3
# with:
# name: 'Linux Map Tools [${{ inputs.configuration }}]'
# path: |
# ${{inputs.branch}}/game/bin/vbsp
# ${{inputs.branch}}/game/bin/vvis
# ${{inputs.branch}}/game/bin/vvis_dll.so
# ${{inputs.branch}}/game/bin/vrad
# ${{inputs.branch}}/game/bin/vrad_dll.so
# if-no-files-found: error
# For now, don't publish the .dbg files even though we publish .pdb files on Windows
# (they're too big)
- name: Publish everything (Linux)
if: inputs.project-group == 'all'
uses: actions/upload-artifact@v3
with:
name: 'Everything (Linux) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/bin/*.so
!${{inputs.branch}}/game/bin/*_srv.so
${{inputs.branch}}/game/mod_*/bin/*.so
!${{inputs.branch}}/game/mod_*/bin/*_srv.so
if-no-files-found: error

View File

@ -0,0 +1,31 @@
#
# MAPBASE SOURCE 2013 CI
#
# Builds all projects when a pull request to the master branch is opened.
# If you're using a fork of Mapbase, feel free to configure this to meet your repository's needs.
#
# The "mapbase_build-sp" set of workflows can build specific projects depending on what files are changed.
# They are designed around a "develop" branch, but can be configured to target "master" and replace this
# instead (or target a similar branch with a different name)
#
# See mapbase_build-base.yml for more information on how this works.
name: Build All Projects #(SP Release)
on:
pull_request:
branches:
- master
jobs:
everything:
strategy:
matrix:
configuration: [Release, Debug]
uses: ./.github/workflows/mapbase_build-base.yml
with:
configuration: ${{ matrix.configuration }}
branch: 'sp'
project-group: 'all'
solution-name: 'everything'
build-on-linux: true # Disable this if you don't want to compile for Linux

View File

@ -0,0 +1,37 @@
#
# MAPBASE SOURCE 2013 CI
#
# Builds game projects every time a pull request which modifies the game code is opened.
# If you're using a fork of Mapbase, feel free to configure this to meet your repository's needs.
#
# See mapbase_build-base.yml for more information on how this works.
name: Build Game Projects #(SP Release)
on:
pull_request:
branches:
- develop
paths:
- '.github/workflows/mapbase_build-sp-rel-games.yml'
- 'sp/src/vpc_scripts/**'
- 'sp/src/game/**'
- 'sp/src/mathlib/**'
- 'sp/src/responserules/runtime/**'
- 'sp/src/tier1/**'
- 'sp/src/vgui2/vgui_controls/**'
- 'sp/src/vscript/**'
jobs:
games:
strategy:
matrix:
configuration: [Release, Debug]
uses: ./.github/workflows/mapbase_build-base.yml
with:
configuration: ${{ matrix.configuration }}
branch: 'sp'
game: 'episodic' # Change this if your mod is not using HL2/Episodic game projects
project-group: 'game'
solution-name: 'games'
build-on-linux: true # Disable this if you don't want to compile for Linux

View File

@ -0,0 +1,38 @@
#
# MAPBASE SOURCE 2013 CI
#
# Builds map tool projects every time a pull request which modifies the map tool code is opened.
# If you're using a fork of Mapbase, feel free to configure this to meet your repository's needs.
#
# See mapbase_build-base.yml for more information on how this works.
name: Build Map Tool Projects #(SP Release)
on:
pull_request:
branches:
- develop
paths:
- '.github/workflows/mapbase_build-sp-rel-maptools.yml'
- 'sp/src/vpc_scripts/**'
- 'sp/src/utils/vbsp/**'
- 'sp/src/utils/vvis/**'
- 'sp/src/utils/vvis_launcher/**'
- 'sp/src/utils/vrad/**'
- 'sp/src/utils/vrad_launcher/**'
- 'sp/src/mathlib/**'
- 'sp/src/tier1/**'
- 'sp/src/vgui2/vgui_controls/**'
- 'sp/src/vscript/**'
jobs:
maptools:
strategy:
matrix:
configuration: [Release, Debug]
uses: ./.github/workflows/mapbase_build-base.yml
with:
configuration: ${{ matrix.configuration }}
branch: 'sp'
project-group: 'maptools'
solution-name: 'maptools'

View File

@ -0,0 +1,33 @@
#
# MAPBASE SOURCE 2013 CI
#
# Builds shader projects every time a pull request which modifies the shader code is opened.
# If you're using a fork of Mapbase, feel free to configure this to meet your repository's needs.
#
# See mapbase_build-base.yml for more information on how this works.
name: Build Shader Projects #(SP Release)
on:
pull_request:
branches:
- develop
paths:
- '.github/workflows/mapbase_build-sp-rel-shaders.yml'
- 'sp/src/vpc_scripts/**'
- 'sp/src/materialsystem/**'
- 'sp/src/mathlib/**'
jobs:
shaders:
strategy:
matrix:
configuration: [Release, Debug]
uses: ./.github/workflows/mapbase_build-base.yml
with:
configuration: ${{ matrix.configuration }}
branch: 'sp'
game: 'episodic' # Change this if your mod is not using HL2/Episodic game projects
project-group: 'shaders'
solution-name: 'shaders'
build-on-linux: true # Disable this if you don't want to compile for Linux

23
.github/workflows/mapbase_pr.yml vendored Normal file
View File

@ -0,0 +1,23 @@
#
# MAPBASE REPO AUTOMATION
#
# Automatically labels pull requests according to changed file paths.
#
# https://github.com/actions/labeler
name: Pull Request Automation
on: [pull_request]
jobs:
label:
if: github.repository_owner == 'mapbase-source'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

34
README
View File

@ -1,10 +1,10 @@
//=================================================================================================================================================== //=========================================================================================================================
Mapbase v7.0 - Source 2013 Mapbase v7.1 - Source 2013
https://github.com/mapbase-source/source-sdk-2013 https://github.com/mapbase-source/source-sdk-2013
https://www.moddb.com/mods/mapbase https://www.moddb.com/mods/mapbase
//=================================================================================================================================================== //=========================================================================================================================
This repository contains code from Mapbase, a modification of the Source 2013 SDK which serves as a combined package This repository contains code from Mapbase, a modification of the Source 2013 SDK which serves as a combined package
of general-purpose improvements, fixes, and utility features for mods. of general-purpose improvements, fixes, and utility features for mods.
@ -23,7 +23,7 @@ Mapbase's main content in this repository may include:
For more information, view this page: For more information, view this page:
https://github.com/mapbase-source/source-sdk-2013/wiki/Introduction-to-Mapbase https://github.com/mapbase-source/source-sdk-2013/wiki/Introduction-to-Mapbase
//=================================================================================================================================================== //=========================================================================================================================
Mapbase is an open-source project and its contents can be distributed and used at the discretion of its users. However, this project contains content from Mapbase is an open-source project and its contents can be distributed and used at the discretion of its users. However, this project contains content from
a vast number of different sources which have their own licensing or attribution requirements. We try to handle most of that ourselves, but users who plan on a vast number of different sources which have their own licensing or attribution requirements. We try to handle most of that ourselves, but users who plan on
@ -32,7 +32,7 @@ distributing Mapbase content are expected to comply with certain rules.
Up-to-date information about Mapbase content usage and credit are addressed in this article on Mapbase's wiki: Up-to-date information about Mapbase content usage and credit are addressed in this article on Mapbase's wiki:
https://github.com/mapbase-source/source-sdk-2013/wiki/Using-Mapbase-Content https://github.com/mapbase-source/source-sdk-2013/wiki/Using-Mapbase-Content
//=================================================================================================================================================== //=========================================================================================================================
>>>>>>>> EXTERNAL CONTENT USED IN MAPBASE <<<<<<<< >>>>>>>> EXTERNAL CONTENT USED IN MAPBASE <<<<<<<<
@ -69,7 +69,7 @@ including radial fog, rope code, and treesway)
- https://github.com/entropy-zero/source-sdk-2013 (skill_changed game event) - https://github.com/entropy-zero/source-sdk-2013 (skill_changed game event)
- https://github.com/Nbc66/source-sdk-2013-ce/tree/v142 (Base for VS2019 toolset support) - https://github.com/Nbc66/source-sdk-2013-ce/tree/v142 (Base for VS2019 toolset support)
//--------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
Valve Developer Community (VDC) sources: Valve Developer Community (VDC) sources:
@ -97,7 +97,7 @@ interchangeable arms; this may change in the future)
- https://developer.valvesoftware.com/wiki/Func_clip_vphysics ("Start Disabled" keyvalue fix) - https://developer.valvesoftware.com/wiki/Func_clip_vphysics ("Start Disabled" keyvalue fix)
- https://developer.valvesoftware.com/wiki/Importing_CSS_Weapons_Into_HL2 (CS:S viewmodel chirality) - https://developer.valvesoftware.com/wiki/Importing_CSS_Weapons_Into_HL2 (CS:S viewmodel chirality)
//--------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
Direct contributions: Direct contributions:
@ -108,13 +108,18 @@ Direct contributions:
- https://github.com/mapbase-source/source-sdk-2013/pull/116 (vgui_movie_display mute keyvalue from Alivebyte/rzkid) - https://github.com/mapbase-source/source-sdk-2013/pull/116 (vgui_movie_display mute keyvalue from Alivebyte/rzkid)
- https://github.com/mapbase-source/source-sdk-2013/pull/140 (logic_substring entity and icon created by moofemp) - https://github.com/mapbase-source/source-sdk-2013/pull/140 (logic_substring entity and icon created by moofemp)
- https://github.com/mapbase-source/source-sdk-2013/pull/143 (Propper features for VBSP from Matty-64) - https://github.com/mapbase-source/source-sdk-2013/pull/143 (Propper features for VBSP from Matty-64)
- https://github.com/mapbase-source/source-sdk-2013/pull/174 (Fix for multiply defined symbols in later toolsets from und)
- https://github.com/mapbase-source/source-sdk-2013/issues/201 (env_projectedtexture shadow filter keyvalue from celisej567)
- https://github.com/mapbase-source/source-sdk-2013/pull/193 (RTB:R info_particle_system_coordinate by arbabf and Iridium77)
- https://github.com/mapbase-source/source-sdk-2013/pull/193 (Infinite prop_interactable cooldown by arbabf)
- Demo autorecord code provided by Klems - Demo autorecord code provided by Klems
- cc_emit crash fix provided by 1upD - cc_emit crash fix provided by 1upD
- Custom HL2 ammo crate models created by Rara (Textures created by Blixibon; This is asset-based and, aside from the SLAM crate, not reflected in the code) - Custom HL2 ammo crate models created by Rykah (Textures created by Blixibon; This is asset-based and, aside from the SLAM crate, not reflected in the code)
- Combine lock hardware on door01_left.mdl created by Kralich (This is asset-based and not reflected in the code) - Combine lock hardware on door01_left.mdl created by Kralich (This is asset-based and not reflected in the code)
- npc_vehicledriver fixes provided by CrAzY - npc_vehicledriver fixes provided by CrAzY
- npc_combine cover behavior patches provided by iohnnyboy - npc_combine cover behavior patches provided by iohnnyboy
- logic_playmovie icon created by URAKOLOUY5 (This is asset-based and not reflected in the code) - logic_playmovie icon created by URAKOLOUY5 (This is asset-based and not reflected in the code)
- Dropship APC save/load fix provided by Cvoxulary
== Contributions from samisalreadytaken: == Contributions from samisalreadytaken:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/47 (VScript utility/consistency changes) =-- https://github.com/mapbase-source/source-sdk-2013/pull/47 (VScript utility/consistency changes)
@ -126,9 +131,12 @@ Direct contributions:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/148 (Minor fixup) =-- https://github.com/mapbase-source/source-sdk-2013/pull/148 (Minor fixup)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/167 (Security fixes) =-- https://github.com/mapbase-source/source-sdk-2013/pull/167 (Security fixes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/168 (Squirrel update) =-- https://github.com/mapbase-source/source-sdk-2013/pull/168 (Squirrel update)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/169 (VScript VGUI)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/171 (VScript documentation sorting) =-- https://github.com/mapbase-source/source-sdk-2013/pull/171 (VScript documentation sorting)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/173 (VScript fixes and optimizations) =-- https://github.com/mapbase-source/source-sdk-2013/pull/173 (VScript fixes and optimizations)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/192 (VScript hook manager and fixes) =-- https://github.com/mapbase-source/source-sdk-2013/pull/192 (VScript hook manager and fixes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/206 (Fix CScriptNetMsgHelper::WriteEntity())
=-- https://github.com/mapbase-source/source-sdk-2013/pull/213 (VScript HUD visibility control, optimizations for 3D skybox angles/fake worldportals)
== Contributions from z33ky: == Contributions from z33ky:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/21 (Various GCC/Linux compilation fixes) =-- https://github.com/mapbase-source/source-sdk-2013/pull/21 (Various GCC/Linux compilation fixes)
@ -149,7 +157,7 @@ Direct contributions:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/185 (Fix enemyfinders becoming visible when they wake) =-- https://github.com/mapbase-source/source-sdk-2013/pull/185 (Fix enemyfinders becoming visible when they wake)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/186 (Fix for brightly glowing teeth) =-- https://github.com/mapbase-source/source-sdk-2013/pull/186 (Fix for brightly glowing teeth)
//--------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
Other sources: Other sources:
@ -167,11 +175,11 @@ Other sources:
- Vortigaunt LOS fix originally created by dky.tehkingd.u for HL2:CE - Vortigaunt LOS fix originally created by dky.tehkingd.u for HL2:CE
- https://combineoverwiki.net/wiki/File:Combine_main_symbol.svg ("icon_combine" instructor icon in "materials/vgui/hud/gameinstructor_hl2_1"; This is asset-based and not reflected in the code) - https://combineoverwiki.net/wiki/File:Combine_main_symbol.svg ("icon_combine" instructor icon in "materials/vgui/hud/gameinstructor_hl2_1"; This is asset-based and not reflected in the code)
//--------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
If there is anything missing from this list, please contact Blixibon. If there is anything missing from this list, please contact Blixibon.
//=================================================================================================================================================== //=========================================================================================================================
Aside from the content list above, Mapbase has more descriptive and up-to-date credits on this wiki article: Aside from the content list above, Mapbase has more descriptive and up-to-date credits on this wiki article:
https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits
@ -180,11 +188,11 @@ Other relevant articles:
* https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Disclaimers * https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Disclaimers
* https://github.com/mapbase-source/source-sdk-2013/wiki/Frequently-Asked-Questions-(FAQ) * https://github.com/mapbase-source/source-sdk-2013/wiki/Frequently-Asked-Questions-(FAQ)
//--------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
In memory of Holly Liberatore (moofemp) In memory of Holly Liberatore (moofemp)
//=================================================================================================================================================== //=========================================================================================================================
Please see the Source SDK 2013 license below: Please see the Source SDK 2013 license below:

5
sp/src/createmaptoolsprojects Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
pushd `dirname $0`
devtools/bin/vpc /hl2 /episodic +maptools /mksln maptools
popd

View File

@ -0,0 +1 @@
devtools\bin\vpc.exe +maptools /mksln maptools.sln

5
sp/src/createshadersprojects Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
pushd `dirname $0`
devtools/bin/vpc /hl2 /episodic +shaders /mksln shaders
popd

View File

@ -0,0 +1 @@
devtools\bin\vpc.exe /hl2 /episodic +shaders /mksln shaders.sln

View File

@ -11,6 +11,6 @@ $(MAKEFILE_LINK): $(shell which $(CXX)) $(THISFILE) $(SRCROOT)/devtools/gcc9+sup
@ if [ "$(shell printf "$(shell $(CXX) -dumpversion)\n8" | sort -Vr | head -1)" = 8 ]; then \ @ if [ "$(shell printf "$(shell $(CXX) -dumpversion)\n8" | sort -Vr | head -1)" = 8 ]; then \
ln -sf $(MAKEFILE_BASE).default $@ ;\ ln -sf $(MAKEFILE_BASE).default $@ ;\
else \ else \
$(COMPILE.cpp) -o $(SRCROOT)/devtools/gcc9+support.o $(SRCROOT)/devtools/gcc9+support.cpp &&\ $(COMPILE.cpp) -m32 -o $(SRCROOT)/devtools/gcc9+support.o $(SRCROOT)/devtools/gcc9+support.cpp &&\
ln -sf $(MAKEFILE_BASE).gcc8 $@ ;\ ln -sf $(MAKEFILE_BASE).gcc8 $@ ;\
fi fi

View File

@ -92,6 +92,7 @@ private:
float m_flLinearAtten; float m_flLinearAtten;
float m_flQuadraticAtten; float m_flQuadraticAtten;
float m_flShadowAtten; float m_flShadowAtten;
float m_flShadowFilter;
bool m_bAlwaysDraw; bool m_bAlwaysDraw;
//bool m_bProjectedTextureVersion; //bool m_bProjectedTextureVersion;

View File

@ -60,6 +60,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvPro
RecvPropFloat( RECVINFO( m_flLinearAtten ) ), RecvPropFloat( RECVINFO( m_flLinearAtten ) ),
RecvPropFloat( RECVINFO( m_flQuadraticAtten ) ), RecvPropFloat( RECVINFO( m_flQuadraticAtten ) ),
RecvPropFloat( RECVINFO( m_flShadowAtten ) ), RecvPropFloat( RECVINFO( m_flShadowAtten ) ),
RecvPropFloat( RECVINFO( m_flShadowFilter ) ),
RecvPropBool( RECVINFO( m_bAlwaysDraw ) ), RecvPropBool( RECVINFO( m_bAlwaysDraw ) ),
// Not needed on the client right now, change when it actually is needed // Not needed on the client right now, change when it actually is needed
@ -97,6 +98,7 @@ C_EnvProjectedTexture *C_EnvProjectedTexture::Create( )
pEnt->m_flLinearAtten = 100.0f; pEnt->m_flLinearAtten = 100.0f;
pEnt->m_flQuadraticAtten = 0.0f; pEnt->m_flQuadraticAtten = 0.0f;
pEnt->m_flShadowAtten = 0.0f; pEnt->m_flShadowAtten = 0.0f;
pEnt->m_flShadowFilter = 0.5f;
//pEnt->m_bProjectedTextureVersion = 1; //pEnt->m_bProjectedTextureVersion = 1;
#endif #endif
@ -403,6 +405,7 @@ void C_EnvProjectedTexture::UpdateLight( void )
state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();
state.m_flShadowAtten = m_flShadowAtten; state.m_flShadowAtten = m_flShadowAtten;
state.m_flShadowFilterSize = m_flShadowFilter;
#else #else
state.m_fQuadraticAtten = 0.0; state.m_fQuadraticAtten = 0.0;
state.m_fLinearAtten = 100; state.m_fLinearAtten = 100;

View File

@ -42,6 +42,7 @@ protected:
EHANDLE m_hControlPointEnts[kMAXCONTROLPOINTS]; EHANDLE m_hControlPointEnts[kMAXCONTROLPOINTS];
Vector m_vControlPointVecs[kMAXCONTROLPOINTS];
// SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ), // SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ),
unsigned char m_iControlPointParents[kMAXCONTROLPOINTS]; unsigned char m_iControlPointParents[kMAXCONTROLPOINTS];
@ -65,6 +66,7 @@ BEGIN_RECV_TABLE_NOBASE( C_ParticleSystem, DT_ParticleSystem )
RecvPropFloat( RECVINFO( m_flStartTime ) ), RecvPropFloat( RECVINFO( m_flStartTime ) ),
RecvPropArray3( RECVINFO_ARRAY(m_hControlPointEnts), RecvPropEHandle( RECVINFO( m_hControlPointEnts[0] ) ) ), RecvPropArray3( RECVINFO_ARRAY(m_hControlPointEnts), RecvPropEHandle( RECVINFO( m_hControlPointEnts[0] ) ) ),
RecvPropArray3( RECVINFO_ARRAY(m_vControlPointVecs), RecvPropVector( RECVINFO( m_vControlPointVecs[0] ) ) ),
RecvPropArray3( RECVINFO_ARRAY(m_iControlPointParents), RecvPropInt( RECVINFO(m_iControlPointParents[0]))), RecvPropArray3( RECVINFO_ARRAY(m_iControlPointParents), RecvPropInt( RECVINFO(m_iControlPointParents[0]))),
RecvPropBool( RECVINFO( m_bWeatherEffect ) ), RecvPropBool( RECVINFO( m_bWeatherEffect ) ),
END_RECV_TABLE(); END_RECV_TABLE();
@ -150,21 +152,41 @@ void C_ParticleSystem::ClientThink( void )
AssertMsg1( pEffect, "Particle system couldn't make %s", pszName ); AssertMsg1( pEffect, "Particle system couldn't make %s", pszName );
if (pEffect) if (pEffect)
{ {
for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) if (m_vControlPointVecs[0] != GetAbsOrigin() && m_hControlPointEnts[0] == NULL)
{ {
CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); // we are using info_particle_system_coordinate
if ( pOnEntity ) for (int i = 0; i < kMAXCONTROLPOINTS; ++i)
{ {
ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); ParticleProp()->AddControlPoint(pEffect, i + 1, this, PATTACH_WORLDORIGIN, 0, m_vControlPointVecs[i] - GetAbsOrigin());
AssertMsg2(m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS,
"Particle system specified bogus control point parent (%d) for point %d.",
m_iControlPointParents[i], i);
if (m_iControlPointParents[i] != 0)
{
pEffect->SetControlPointParent(i + 1, m_iControlPointParents[i]);
}
} }
}
AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , else
"Particle system specified bogus control point parent (%d) for point %d.", {
m_iControlPointParents[i], i ); for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i )
if (m_iControlPointParents[i] != 0)
{ {
pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get();
if ( pOnEntity )
{
ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW );
}
AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS ,
"Particle system specified bogus control point parent (%d) for point %d.",
m_iControlPointParents[i], i );
if (m_iControlPointParents[i] != 0)
{
pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]);
}
} }
} }

View File

@ -1705,13 +1705,16 @@ void CHudCommentary::FixupCommentaryLabels( const char *pszPrintName, const char
} }
else else
{ {
static wchar_t iszPrintNameLocalized[MAX_SPEAKER_NAME]; static wchar_t iszSpeakersLocalized[MAX_SPEAKER_NAME] = { 0 };
static wchar_t iszPrintNameLocalized[MAX_SPEAKER_NAME] = { 0 };
wcsncpy( iszSpeakersLocalized, m_szSpeakers, sizeof( iszSpeakersLocalized ) / sizeof( wchar_t ) );
if (m_szSpeakers[0] == '#') if (m_szSpeakers[0] == '#')
{ {
wchar_t *pwszSpeakers = g_pVGuiLocalize->Find( pszSpeakers ); wchar_t *pwszSpeakers = g_pVGuiLocalize->Find( pszSpeakers );
if (pwszSpeakers) if (pwszSpeakers)
wcsncpy( m_szSpeakers, pwszSpeakers, sizeof( m_szSpeakers ) / sizeof( wchar_t ) ); wcsncpy( iszSpeakersLocalized, pwszSpeakers, sizeof( iszSpeakersLocalized ) / sizeof( wchar_t ) );
} }
if (pszPrintName[0] == '#' && pszLocal) if (pszPrintName[0] == '#' && pszLocal)
@ -1719,7 +1722,7 @@ void CHudCommentary::FixupCommentaryLabels( const char *pszPrintName, const char
else else
g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, iszPrintNameLocalized, sizeof( iszPrintNameLocalized ) ); g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, iszPrintNameLocalized, sizeof( iszPrintNameLocalized ) );
V_snwprintf( m_szSpeakers, sizeof( m_szSpeakers ), L"%ls ~ %ls", m_szSpeakers, iszPrintNameLocalized ); V_snwprintf( m_szSpeakers, sizeof( m_szSpeakers ), L"%ls ~ %ls", iszSpeakersLocalized, iszPrintNameLocalized );
} }
} }

View File

@ -71,7 +71,6 @@ $Configuration
$SystemFrameworks "Carbon" [$OSXALL] $SystemFrameworks "Carbon" [$OSXALL]
$SystemLibraries "rt" [$LINUXALL] $SystemLibraries "rt" [$LINUXALL]
$IgnoreImportLibrary "TRUE" $IgnoreImportLibrary "TRUE"
$AdditionalOptions "$BASE /force:multiple" [($VS2015||$VS2017||$VS2019||$VS2022)] // Required to fix _hypot in particles.lib (this may be a temporary solution)
$AdditionalDependencies "$BASE winmm.lib" [$WIN32] $AdditionalDependencies "$BASE winmm.lib" [$WIN32]
$AdditionalDependencies "$BASE wsock32.lib Ws2_32.lib" [$BUILD_REPLAY] $AdditionalDependencies "$BASE wsock32.lib Ws2_32.lib" [$BUILD_REPLAY]
} }
@ -1261,6 +1260,9 @@ $Project
$Lib vtf $Lib vtf
$ImpLib steam_api $ImpLib steam_api
// Discord integration
$Lib "$LIBPUBLIC\discord-rpc" [$MAPBASE_RPC&&!$LINUXALL]
$Lib $LIBCOMMON/libcrypto [$POSIX] $Lib $LIBCOMMON/libcrypto [$POSIX]
$ImpLib "$LIBCOMMON\curl" [$OSXALL] $ImpLib "$LIBCOMMON\curl" [$OSXALL]

View File

@ -10,7 +10,7 @@ $Configuration
{ {
$PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE" $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE"
$PreprocessorDefinitions "$BASE;MAPBASE_RPC;DISCORD_RPC;STEAM_RPC" [$MAPBASE_RPC] $PreprocessorDefinitions "$BASE;MAPBASE_RPC;DISCORD_RPC;STEAM_RPC" [$MAPBASE_RPC&&!$LINUXALL]
$PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT]
$PreprocessorDefinitions "$BASE;NEW_RESPONSE_SYSTEM" [$NEW_RESPONSE_SYSTEM] $PreprocessorDefinitions "$BASE;NEW_RESPONSE_SYSTEM" [$NEW_RESPONSE_SYSTEM]
} }
@ -59,7 +59,11 @@ $Project
$File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.cpp" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.h" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.h" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\logic_script_client.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\logic_script_client.cpp" [$MAPBASE_VSCRIPT]
$File "mapbase\vscript_vgui.cpp" [$MAPBASE_VSCRIPT]
$File "mapbase\vscript_vgui.h" [$MAPBASE_VSCRIPT]
$File "mapbase\vscript_vgui.nut" [$MAPBASE_VSCRIPT]
$File "mapbase\c_func_clientclip.cpp" $File "mapbase\c_func_clientclip.cpp"
$File "mapbase\c_func_fake_worldportal.cpp" $File "mapbase\c_func_fake_worldportal.cpp"
$File "mapbase\c_func_fake_worldportal.h" $File "mapbase\c_func_fake_worldportal.h"

View File

@ -644,6 +644,15 @@ void CHudWeaponSelection::Paint()
// This is a bit of a misnomer... we really are asking "Is this the selected slot"? // This is a bit of a misnomer... we really are asking "Is this the selected slot"?
selectedWeapon = true; selectedWeapon = true;
} }
#ifdef MAPBASE
else if (!hud_showemptyweaponslots.GetBool() && !pWeapon)
{
// Revert the offset
xPos -= ( m_flMediumBoxWide + 5 ) * xModifiers[ i ];
yPos -= ( m_flMediumBoxTall + 5 ) * yModifiers[ i ];
continue;
}
#endif
// Draw the box with the appropriate icon // Draw the box with the appropriate icon
DrawLargeWeaponBox( pWeapon, DrawLargeWeaponBox( pWeapon,
@ -1375,6 +1384,23 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot )
// Changing vertical/horizontal direction. Reset the selected box position to zero. // Changing vertical/horizontal direction. Reset the selected box position to zero.
m_iSelectedBoxPosition = 0; m_iSelectedBoxPosition = 0;
m_iSelectedSlot = iWeaponSlot; m_iSelectedSlot = iWeaponSlot;
#ifdef MAPBASE
if (!hud_showemptyweaponslots.GetBool())
{
// Skip empty slots
int i = 0;
while ( i < MAX_WEAPON_POSITIONS )
{
C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( iWeaponSlot, i );
if ( pWeapon )
break;
i++;
}
m_iSelectedBoxPosition = i;
}
#endif
} }
else else
{ {
@ -1385,6 +1411,27 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot )
// Decrementing within the slot. If we're at the zero position in this slot, // Decrementing within the slot. If we're at the zero position in this slot,
// jump to the zero position of the opposite slot. This also counts as our increment. // jump to the zero position of the opposite slot. This also counts as our increment.
increment = -1; increment = -1;
#ifdef MAPBASE
if (!hud_showemptyweaponslots.GetBool())
{
// Skip empty slots
int iZeroPos = 0;
while ( iZeroPos < MAX_WEAPON_POSITIONS )
{
C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, iZeroPos );
if ( pWeapon )
break;
iZeroPos++;
}
if ( iZeroPos == m_iSelectedBoxPosition )
{
newSlot = ( m_iSelectedSlot + 2 ) % 4;
m_iSelectedBoxPosition = increment = 0;
}
}
else
#endif
if ( 0 == m_iSelectedBoxPosition ) if ( 0 == m_iSelectedBoxPosition )
{ {
newSlot = ( m_iSelectedSlot + 2 ) % 4; newSlot = ( m_iSelectedSlot + 2 ) % 4;
@ -1402,6 +1449,35 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot )
lastSlotPos = slotPos; lastSlotPos = slotPos;
} }
} }
#ifdef MAPBASE
if (!hud_showemptyweaponslots.GetBool())
{
// Skip empty slots
int i = m_iSelectedBoxPosition + increment;
while ( i >= 0 && i < lastSlotPos )
{
C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( newSlot, i );
if ( !pWeapon )
{
if (increment < 0)
{
increment--;
i--;
}
else
{
increment++;
i++;
}
}
else
{
break;
}
}
}
#endif
// Increment/Decrement the selected box position // Increment/Decrement the selected box position
if ( m_iSelectedBoxPosition + increment <= lastSlotPos ) if ( m_iSelectedBoxPosition + increment <= lastSlotPos )

View File

@ -58,6 +58,9 @@ public:
// Hidden bits. // Hidden bits.
// HIDEHUD_ flags that note when this element should be hidden in the HUD // HIDEHUD_ flags that note when this element should be hidden in the HUD
virtual void SetHiddenBits( int iBits ); virtual void SetHiddenBits( int iBits );
#ifdef MAPBASE_VSCRIPT
int GetHiddenBits() const { return m_iHiddenBits; }
#endif
bool IsParentedToClientDLLRootPanel() const; bool IsParentedToClientDLLRootPanel() const;
void SetParentedToClientDLLRootPanel( bool parented ); void SetParentedToClientDLLRootPanel( bool parented );

View File

@ -58,70 +58,11 @@ bool C_FuncFakeWorldPortal::ShouldDraw()
} }
//-----------------------------------------------------------------------------
// Do we have a fake world portal in view?
//-----------------------------------------------------------------------------
C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane )
{
// Early out if no cameras
C_FuncFakeWorldPortal *pReflectiveGlass = GetFakeWorldPortalList();
if ( !pReflectiveGlass )
return NULL;
Frustum_t frustum;
GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum );
cplane_t localPlane;
Vector vecOrigin, vecWorld, vecDelta, vecForward;
AngleVectors( view.angles, &vecForward, NULL, NULL );
for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext )
{
if ( pReflectiveGlass->IsDormant() )
continue;
if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) )
continue;
Vector vecMins, vecMaxs;
pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs );
if ( R_CullBox( vecMins, vecMaxs, frustum ) )
continue;
const model_t *pModel = pReflectiveGlass->GetModel();
const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform();
int nCount = modelinfo->GetBrushModelPlaneCount( pModel );
for ( int i = 0; i < nCount; ++i )
{
modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin );
MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space
VectorTransform( vecOrigin, mat, vecWorld );
if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane
continue;
VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull
if ( vecDelta.Dot( plane.normal ) >= 0 )
continue;
// Must have valid plane
if ( !pReflectiveGlass->m_hTargetPlane )
continue;
return pReflectiveGlass;
}
}
return NULL;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Iterates through fake world portals instead of just picking one // Iterates through fake world portals instead of just picking one
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view,
cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum ) Vector &vecAbsPlaneNormal, float &flLocalPlaneDist, const Frustum_t &frustum )
{ {
// Early out if no cameras // Early out if no cameras
C_FuncFakeWorldPortal *pReflectiveGlass = NULL; C_FuncFakeWorldPortal *pReflectiveGlass = NULL;
@ -130,8 +71,9 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const
else else
pReflectiveGlass = pStart->m_pNext; pReflectiveGlass = pStart->m_pNext;
cplane_t localPlane; cplane_t localPlane, worldPlane;
Vector vecOrigin, vecWorld, vecDelta; Vector vecMins, vecMaxs, vecLocalOrigin, vecAbsOrigin, vecDelta;
for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext )
{ {
if ( pReflectiveGlass->IsDormant() ) if ( pReflectiveGlass->IsDormant() )
@ -140,7 +82,10 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const
if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) ) if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) )
continue; continue;
Vector vecMins, vecMaxs; // Must have valid plane
if ( !pReflectiveGlass->m_hTargetPlane )
continue;
pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs );
if ( R_CullBox( vecMins, vecMaxs, frustum ) ) if ( R_CullBox( vecMins, vecMaxs, frustum ) )
continue; continue;
@ -151,23 +96,22 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const
int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); int nCount = modelinfo->GetBrushModelPlaneCount( pModel );
for ( int i = 0; i < nCount; ++i ) for ( int i = 0; i < nCount; ++i )
{ {
modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin ); modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecLocalOrigin );
MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space MatrixTransformPlane( mat, localPlane, worldPlane ); // Transform to world space
VectorTransform( vecOrigin, mat, vecWorld );
if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane if ( view.origin.Dot( worldPlane.normal ) <= worldPlane.dist ) // Check for view behind plane
continue; continue;
VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull VectorTransform( vecLocalOrigin, mat, vecAbsOrigin );
if ( vecDelta.Dot( plane.normal ) >= 0 ) VectorSubtract( vecAbsOrigin, view.origin, vecDelta );
if ( vecDelta.Dot( worldPlane.normal ) >= 0 ) // Backface cull
continue; continue;
// Must have valid plane flLocalPlaneDist = localPlane.dist;
if ( !pReflectiveGlass->m_hTargetPlane ) vecAbsPlaneNormal = worldPlane.normal;
continue;
vecPlaneOrigin = vecOrigin;
return pReflectiveGlass; return pReflectiveGlass;
} }
} }

View File

@ -53,10 +53,8 @@ public:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Do we have reflective glass in view? If so, what's the reflection plane? // Do we have reflective glass in view? If so, what's the reflection plane?
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane );
C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view,
cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum ); Vector &vecAbsPlaneNormal, float &flLocalPlaneDist, const Frustum_t &frustum );
#endif // C_FUNC_FAKE_WORLDPORTAL #endif // C_FUNC_FAKE_WORLDPORTAL

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef VSCRIPT_VGUI_H
#define VSCRIPT_VGUI_H
#ifdef _WIN32
#pragma once
#endif
void RegisterScriptVGUI();
#endif

View File

@ -0,0 +1,394 @@
static const char* g_Script_vgui_init = R"script(
local DoCreateFont = ISurface.CreateFont;
ISurface.CreateFont <- function( name, props )
{
if ( !("name" in props) || typeof props.name != "string" )
throw "invalid parameter 'name'";
if ( !("tall" in props) || typeof props.tall != "integer" || !props.tall )
throw "invalid parameter 'tall'";
if ( !("weight" in props) || typeof props.weight != "integer" )
throw "invalid parameter 'weight'";
local yres_min = 0, yres_max = 0;
if ( "yres" in props && typeof props.yres == "string" )
{
local ss = ::split( props.yres, " " );
try
{
yres_min = ss[0].tointeger();
yres_max = ss[1].tointeger();
}
catch(x)
{
throw "invalid parameter 'yres'";
}
}
if ( ( (!("proportional" in props) || typeof props.proportional != "bool") ) && !yres_min )
{
throw "parameter 'proportional' or 'yres' not found";
}
else if ( "proportional" in props && props.proportional && yres_min )
{
throw "resolution definition on a proportional font"
}
local blur = 0, scanlines = 0, proportional = false, flags = 0;
if ( "blur" in props && typeof props.blur == "integer" )
blur = props.blur;
if ( "scanlines" in props && typeof props.scanlines == "integer" )
scanlines = props.scanlines;
if ( "proportional" in props && typeof props.proportional == "bool" )
proportional = props.proportional;
if ( "italic" in props && props.italic == true )
flags = flags | 0x001;
if ( "underline" in props && props.underline == true )
flags = flags | 0x002;
if ( "strikeout" in props && props.strikeout == true )
flags = flags | 0x004;
if ( "symbol" in props && props.symbol == true )
flags = flags | 0x008;
if ( "antialias" in props && props.antialias == true )
flags = flags | 0x010;
if ( "gaussianblur" in props && props.gaussianblur == true )
flags = flags | 0x020;
if ( "rotary" in props && props.rotary == true )
flags = flags | 0x040;
if ( "dropshadow" in props && props.dropshadow == true )
flags = flags | 0x080;
if ( "additive" in props && props.additive == true )
flags = flags | 0x100;
if ( "outline" in props && props.outline == true )
flags = flags | 0x200;
if ( "custom" in props && props.custom == true )
flags = flags | 0x400;
if ( "bitmap" in props && props.bitmap == true )
flags = flags | 0x800;
return DoCreateFont( name, props.name, props.tall, props.weight, blur, scanlines, flags, yres_min, yres_max, proportional );
}
local _Schemes = {}
local _FontTall = {}
local DoGetFont = ISurface.DoGetFont <- ISurface.GetFont;
local DoGetFontTall = ISurface.GetFontTall;
ISurface.GetFont <- function( name, proportional, sch = "" )
{
if ( sch in _Schemes )
{
local fonts = _Schemes[sch][proportional.tointeger()];
if ( name in fonts )
return fonts[name];
}
else
{
if ( typeof sch != "string" )
throw "invalid parameter 'scheme'";
_Schemes[sch] <- [{}, {}];
}
local id = DoGetFont( name, proportional, sch );
if ( id > 0 )
_Schemes[sch][proportional.tointeger()][name] <- id;
return id;
}
ISurface.GetFontTall <- function( id )
{
if ( id in _FontTall )
return _FontTall[id];
return _FontTall[id] <- DoGetFontTall( id );
}
local _Textures = {}
local DoGetTextureID = ISurface.GetTextureID;
local DoValidateTexture = ISurface.ValidateTexture;
local DoSetTextureFile = ISurface.SetTextureFile;
ISurface.ValidateTexture <- function( filename, hardwareFilter, forceReload = false, procedural = false )
{
return DoValidateTexture( filename, hardwareFilter, forceReload, procedural );
}
ISurface.SetTextureFile <- function( id, filename, hardwareFilter )
{
if ( filename in _Textures )
delete _Textures[filename];
return DoSetTextureFile( id, filename, hardwareFilter );
}
ISurface.GetTextureID <- function( name )
{
if ( name in _Textures )
return _Textures[name];
local id = DoGetTextureID( name );
if ( id > 0 )
_Textures[name] <- id;
return id;
}
// Forward compatibility
IVGui.GetRootPanel <- function() { return 1000 }
//IVGui.GetGameUIRootPanel <- function() { return 1001 }
IVGui.GetClientDLLRootPanel <- function() { return 1002 }
//IVGui.GetHudViewportPanel <- function() { return 1010 }
local CreatePanel = IVGui.CreatePanel;
IVGui.CreatePanel <- function( type, parent, name )
{
if ( !parent )
throw "invalid parent";
local root = 0;
if ( typeof parent == "integer" )
{
switch ( parent )
{
case 1000:
root = 0;
break;
case 1002:
root = 2;
break;
default:
throw "invalid parent";
}
parent = null;
}
return CreatePanel( type, parent, name, root );
}
ISurface.__OnScreenSizeChanged <- function()
{
_FontTall.clear();
}
// MAX_JOYSTICKS = 1 // ( 1 << MAX_SPLITSCREEN_CLIENT_BITS )
// MAX_JOYSTICK_AXES = 6 // X,Y,Z,R,U,V
// JOYSTICK_MAX_BUTTON_COUNT = 32
// JOYSTICK_POV_BUTTON_COUNT = 4
// JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2
enum ButtonCode
{
KEY_FIRST = 0
KEY_0 = 1
KEY_1 = 2
KEY_2 = 3
KEY_3 = 4
KEY_4 = 5
KEY_5 = 6
KEY_6 = 7
KEY_7 = 8
KEY_8 = 9
KEY_9 = 10
KEY_A = 11
KEY_B = 12
KEY_C = 13
KEY_D = 14
KEY_E = 15
KEY_F = 16
KEY_G = 17
KEY_H = 18
KEY_I = 19
KEY_J = 20
KEY_K = 21
KEY_L = 22
KEY_M = 23
KEY_N = 24
KEY_O = 25
KEY_P = 26
KEY_Q = 27
KEY_R = 28
KEY_S = 29
KEY_T = 30
KEY_U = 31
KEY_V = 32
KEY_W = 33
KEY_X = 34
KEY_Y = 35
KEY_Z = 36
KEY_PAD_0 = 37
KEY_PAD_1 = 38
KEY_PAD_2 = 39
KEY_PAD_3 = 40
KEY_PAD_4 = 41
KEY_PAD_5 = 42
KEY_PAD_6 = 43
KEY_PAD_7 = 44
KEY_PAD_8 = 45
KEY_PAD_9 = 46
KEY_PAD_DIVIDE = 47
KEY_PAD_MULTIPLY = 48
KEY_PAD_MINUS = 49
KEY_PAD_PLUS = 50
KEY_PAD_ENTER = 51
KEY_PAD_DECIMAL = 52
KEY_LBRACKET = 53
KEY_RBRACKET = 54
KEY_SEMICOLON = 55
KEY_APOSTROPHE = 56
KEY_BACKQUOTE = 57
KEY_COMMA = 58
KEY_PERIOD = 59
KEY_SLASH = 60
KEY_BACKSLASH = 61
KEY_MINUS = 62
KEY_EQUAL = 63
KEY_ENTER = 64
KEY_SPACE = 65
KEY_BACKSPACE = 66
KEY_TAB = 67
KEY_CAPSLOCK = 68
KEY_NUMLOCK = 69
KEY_ESCAPE = 70
KEY_SCROLLLOCK = 71
KEY_INSERT = 72
KEY_DELETE = 73
KEY_HOME = 74
KEY_END = 75
KEY_PAGEUP = 76
KEY_PAGEDOWN = 77
KEY_BREAK = 78
KEY_LSHIFT = 79
KEY_RSHIFT = 80
KEY_LALT = 81
KEY_RALT = 82
KEY_LCONTROL = 83
KEY_RCONTROL = 84
KEY_LWIN = 85
KEY_RWIN = 86
KEY_APP = 87
KEY_UP = 88
KEY_LEFT = 89
KEY_DOWN = 90
KEY_RIGHT = 91
KEY_F1 = 92
KEY_F2 = 93
KEY_F3 = 94
KEY_F4 = 95
KEY_F5 = 96
KEY_F6 = 97
KEY_F7 = 98
KEY_F8 = 99
KEY_F9 = 100
KEY_F10 = 101
KEY_F11 = 102
KEY_F12 = 103
KEY_CAPSLOCKTOGGLE = 104
KEY_NUMLOCKTOGGLE = 105
KEY_SCROLLLOCKTOGGLE = 106
KEY_LAST = 106
MOUSE_FIRST = 107
MOUSE_LEFT = 107
MOUSE_RIGHT = 108
MOUSE_MIDDLE = 109
MOUSE_4 = 110
MOUSE_5 = 111
MOUSE_WHEEL_UP = 112
MOUSE_WHEEL_DOWN = 113
MOUSE_LAST = 113
JOYSTICK_FIRST = 114
JOYSTICK_FIRST_BUTTON = 114
JOYSTICK_LAST_BUTTON = 145
JOYSTICK_FIRST_POV_BUTTON = 146
JOYSTICK_LAST_POV_BUTTON = 149
JOYSTICK_FIRST_AXIS_BUTTON = 150
JOYSTICK_LAST_AXIS_BUTTON = 161
JOYSTICK_LAST = 161
}
enum AnalogCode
{
MOUSE_X = 0
MOUSE_Y = 1
MOUSE_XY = 2
MOUSE_WHEEL = 3
JOYSTICK_FIRST_AXIS = 4
JOYSTICK_LAST_AXIS = 9
}
enum CursorCode
{
dc_none = 1
dc_arrow = 2
dc_ibeam = 3
dc_hourglass = 4
dc_waitarrow = 5
dc_crosshair = 6
dc_up = 7
dc_sizenwse = 8
dc_sizenesw = 9
dc_sizewe = 10
dc_sizens = 11
dc_sizeall = 12
dc_no = 13
dc_hand = 14
dc_blank = 15
}
enum Alignment
{
northwest = 0
north = 1
northeast = 2
west = 3
center = 4
east = 5
southwest = 6
south = 7
southeast = 8
}
if ( __Documentation.RegisterHelp != dummy )
{
local RegEnum = function( e )
{
local K = getconsttable()[e];
__Documentation.RegisterEnumHelp( e, K.len(), "" );
e += ".";
foreach ( s, v in K )
{
__Documentation.RegisterConstHelp( e+s, v, "" );
}
}
RegEnum( "ButtonCode" );
RegEnum( "AnalogCode" );
RegEnum( "CursorCode" );
RegEnum( "Alignment" );
__Documentation.RegisterHelp( "ISurface::CreateFont", "void ISurface::CreateFont(string, handle)", "" );
__Documentation.RegisterHelp( "IVGui::CreatePanel", "handle IVGui::CreatePanel(string, handle, string)", "" );
__Documentation.RegisterHelp( "IVGui::GetRootPanel", "handle IVGui::GetRootPanel()", "" );
__Documentation.RegisterHelp( "IVGui::GetClientDLLRootPanel", "handle IVGui::GetClientDLLRootPanel()", "" );
}
)script";

View File

@ -409,10 +409,6 @@ protected:
void Enable3dSkyboxFog( void ); void Enable3dSkyboxFog( void );
void DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget, ITexture *pDepthTarget ); void DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget, ITexture *pDepthTarget );
#ifdef MAPBASE
void CalculateSkyAngles( const QAngle &angAngles );
#endif
sky3dparams_t * PreRender3dSkyboxWorld( SkyboxVisibility_t nSkyboxVisible ); sky3dparams_t * PreRender3dSkyboxWorld( SkyboxVisibility_t nSkyboxVisible );
sky3dparams_t *m_pSky3dParams; sky3dparams_t *m_pSky3dParams;
@ -2110,20 +2106,18 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
Frustum_t frustum; Frustum_t frustum;
GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum );
cplane_t portalPlane; Vector vecAbsPlaneNormal;
Vector vecPlaneOrigin; float flLocalPlaneDist;
//C_FuncFakeWorldPortal *pPortalEnt = IsFakeWorldPortalInView( view, portalPlane ); C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, vecAbsPlaneNormal, flLocalPlaneDist, frustum );
//if ( pPortalEnt )
C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, portalPlane, vecPlaneOrigin, frustum );
while ( pPortalEnt != NULL ) while ( pPortalEnt != NULL )
{ {
ITexture *pCameraTarget = pPortalEnt->RenderTarget(); ITexture *pCameraTarget = pPortalEnt->RenderTarget();
int width = pCameraTarget->GetActualWidth(); int width = pCameraTarget->GetActualWidth();
int height = pCameraTarget->GetActualHeight(); int height = pCameraTarget->GetActualHeight();
DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, portalPlane, vecPlaneOrigin ); DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, vecAbsPlaneNormal, flLocalPlaneDist );
pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, portalPlane, vecPlaneOrigin, frustum ); pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, vecAbsPlaneNormal, flLocalPlaneDist, frustum );
} }
#endif #endif
} }
@ -3541,8 +3535,6 @@ bool CViewRender::DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_Poin
} }
#ifdef MAPBASE #ifdef MAPBASE
ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0");
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Sets up scene and renders WIP fake world portal view. // Purpose: Sets up scene and renders WIP fake world portal view.
// Based on code from monitors, mirrors, and logic_measure_movement. // Based on code from monitors, mirrors, and logic_measure_movement.
@ -3559,7 +3551,7 @@ ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0");
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer,
int x, int y, int width, int height, int x, int y, int width, int height,
const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin ) const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, float flLocalPlaneDist )
{ {
#ifdef USE_MONITORS #ifdef USE_MONITORS
VPROF_INCREMENT_COUNTER( "cameras rendered", 1 ); VPROF_INCREMENT_COUNTER( "cameras rendered", 1 );
@ -3590,85 +3582,52 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP
} }
} }
monitorView.width = width;
monitorView.height = height;
monitorView.x = x; monitorView.x = x;
monitorView.y = y; monitorView.y = y;
monitorView.width = width;
monitorView.origin = mainView.origin; monitorView.height = height;
monitorView.angles = mainView.angles;
// Debug stuff
static float flLastDebugTime = 0.0f;
bool bDebug = r_fakeworldportal_debug.GetBool() && gpGlobals->curtime > flLastDebugTime;
//
// Calculate the angles for the fake portal plane
//
QAngle angTargetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles;
QAngle angFakePortalAngles;
// Get vectors from our original angles.
Vector vOurForward, vOurRight, vOurUp;
AngleVectors( pCameraEnt->GetAbsAngles(), &vOurForward, &vOurRight, &vOurUp );
Quaternion quat;
BasisToQuaternion( ourPlane.normal, vOurRight, vOurUp, quat );
QuaternionAngles( quat, angFakePortalAngles );
if (bDebug)
{
// RED - Initial player origin
debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 255, 0, 0, 128, 10.0f );
// YELLOW - Portal origin
debugoverlay->AddBoxOverlay( pCameraEnt->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), angFakePortalAngles, 255, 224, 0, 128, 10.0f );
}
//
// Translate the actual portal view position to be relative to the target
//
matrix3x4_t matPlayer, matPortal, matPlayerToPortal;
AngleIMatrix( monitorView.angles, monitorView.origin, matPlayer );
AngleMatrix( angFakePortalAngles, pCameraEnt->GetAbsOrigin(), matPortal );
ConcatTransforms( matPlayer, matPortal, matPlayerToPortal );
// Apply the scale factor
if ( pCameraEnt->m_flScale > 0 )
{
Vector vecTranslation;
MatrixGetColumn( matPlayerToPortal, 3, vecTranslation );
vecTranslation /= pCameraEnt->m_flScale;
MatrixSetColumn( vecTranslation, 3, matPlayerToPortal );
}
matrix3x4_t matTarget;
AngleMatrix( angTargetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), matTarget );
// Now apply the new matrix to the new reference point
matrix3x4_t matPortalToPlayer, matNewPlayerPosition;
MatrixInvert( matPlayerToPortal, matPortalToPlayer );
ConcatTransforms( matTarget, matPortalToPlayer, matNewPlayerPosition );
MatrixAngles( matNewPlayerPosition, monitorView.angles, monitorView.origin );
if (bDebug)
{
// BLUE - Target origin
debugoverlay->AddBoxOverlay( pCameraEnt->m_hTargetPlane->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), angTargetAngles, 0, 0, 255, 128, 10.0f );
// GREEN - Final origin
debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 0, 255, 0, 128, 10.0f );
flLastDebugTime = gpGlobals->curtime + 5.0f;
}
monitorView.fov = mainView.fov;
monitorView.m_bOrtho = mainView.m_bOrtho; monitorView.m_bOrtho = mainView.m_bOrtho;
monitorView.fov = mainView.fov;
monitorView.m_flAspectRatio = mainView.m_flAspectRatio; monitorView.m_flAspectRatio = mainView.m_flAspectRatio;
monitorView.m_bViewToProjectionOverride = false; monitorView.m_bViewToProjectionOverride = false;
matrix3x4_t worldToView;
AngleIMatrix( mainView.angles, mainView.origin, worldToView );
matrix3x4_t targetToWorld;
{
// NOTE: m_PlaneAngles is angle offset
QAngle targetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles;
AngleMatrix( targetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), targetToWorld );
}
matrix3x4_t portalToWorld;
{
Vector left, up;
VectorVectors( vecAbsPlaneNormal, left, up );
VectorNegate( left );
portalToWorld.Init( vecAbsPlaneNormal, left, up, pCameraEnt->GetAbsOrigin() );
}
matrix3x4_t portalToView;
ConcatTransforms( worldToView, portalToWorld, portalToView );
if ( pCameraEnt->m_flScale > 0.0f )
{
portalToView[0][3] /= pCameraEnt->m_flScale;
portalToView[1][3] /= pCameraEnt->m_flScale;
portalToView[2][3] /= pCameraEnt->m_flScale;
}
matrix3x4_t viewToPortal;
MatrixInvert( portalToView, viewToPortal );
matrix3x4_t newViewToWorld;
ConcatTransforms( targetToWorld, viewToPortal, newViewToWorld );
MatrixAngles( newViewToWorld, monitorView.angles, monitorView.origin );
// @MULTICORE (toml 8/11/2006): this should be a renderer.... // @MULTICORE (toml 8/11/2006): this should be a renderer....
int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL); int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL);
bool bDrew3dSkybox = false; bool bDrew3dSkybox = false;
@ -3691,21 +3650,17 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP
SafeRelease( pSkyView ); SafeRelease( pSkyView );
} }
//
// Make a clipping plane for the target view
//
Vector4D plane; Vector4D plane;
Vector vecAnglesNormal; // target direction
AngleVectors( angTargetAngles, &vecAnglesNormal ); MatrixGetColumn( targetToWorld, 0, plane.AsVector3D() );
VectorNormalize( vecAnglesNormal ); VectorNormalize( plane.AsVector3D() );
VectorCopy( -vecAnglesNormal, plane.AsVector3D() ); VectorNegate( plane.AsVector3D() );
// The portal plane's distance from the actual brush's origin plane.w =
float flPlaneDist = vecPlaneOrigin.Length(); MatrixColumnDotProduct( targetToWorld, 3, plane.AsVector3D() ) // target clip plane distance
- flLocalPlaneDist // portal plane distance on the brush. This distance needs to be accounted for while placing the exit target
// The target's distance from world origin - 0.1;
plane.w = -((pCameraEnt->m_hTargetPlane->GetAbsOrigin() * vecAnglesNormal).Length() + flPlaneDist) + 0.1f;
CMatRenderContextPtr pRenderContext( materials ); CMatRenderContextPtr pRenderContext( materials );
pRenderContext->PushCustomClipPlane( plane.Base() ); pRenderContext->PushCustomClipPlane( plane.Base() );
@ -5400,10 +5355,16 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
// Re-use the x coordinate to determine if we shuld do this with angles // Re-use the x coordinate to determine if we shuld do this with angles
if (m_pSky3dParams->angles.GetX() != 0) if (m_pSky3dParams->angles.GetX() != 0)
{ {
CalculateSkyAngles( m_pSky3dParams->skycamera->GetAbsAngles() ); const matrix3x4_t &matSky = m_pSky3dParams->skycamera->EntityToWorldTransform();
matrix3x4_t matView;
AngleMatrix( angles, origin, matView );
ConcatTransforms( matSky, matView, matView );
MatrixAngles( matView, angles, origin );
}
else
{
VectorAdd( origin, m_pSky3dParams->skycamera->GetAbsOrigin(), origin );
} }
VectorAdd( origin, m_pSky3dParams->skycamera->GetAbsOrigin(), origin );
} }
else else
{ {
@ -5411,10 +5372,16 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
m_pSky3dParams->angles.GetY() != 0 || m_pSky3dParams->angles.GetY() != 0 ||
m_pSky3dParams->angles.GetZ() != 0) m_pSky3dParams->angles.GetZ() != 0)
{ {
CalculateSkyAngles( m_pSky3dParams->angles.Get() ); matrix3x4_t matSky, matView;
AngleMatrix( m_pSky3dParams->angles, m_pSky3dParams->origin, matSky );
AngleMatrix( angles, origin, matView );
ConcatTransforms( matSky, matView, matView );
MatrixAngles( matView, angles, origin );
}
else
{
VectorAdd( origin, m_pSky3dParams->origin, origin );
} }
VectorAdd( origin, m_pSky3dParams->origin, origin );
} }
#else #else
VectorAdd( origin, m_pSky3dParams->origin, origin ); VectorAdd( origin, m_pSky3dParams->origin, origin );
@ -5531,55 +5498,6 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
#endif #endif
} }
#ifdef MAPBASE
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CSkyboxView::CalculateSkyAngles( const QAngle &angAngles )
{
// Unfortunately, it's not as simple as "angles += m_pSky3dParams->angles".
// This stuff took a long time to figure out. I'm glad I got it working.
// First, create a matrix for the sky's angles.
matrix3x4_t matSkyAngles;
AngleMatrix( angAngles, matSkyAngles );
// The code in between the lines below was mostly lifted from projected texture screenspace code and was a huge lifesaver.
// The comments are my attempt at explaining the little I understand of what's going on here.
// ----------------------------------------------------------------------
// These are the vectors that would eventually become our final angle directions.
Vector vecSkyForward, vecSkyRight, vecSkyUp;
// Get vectors from our original angles.
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors( angles, &vPlayerForward, &vPlayerRight, &vPlayerUp );
// Transform them from our sky angles matrix and put the results in those vectors we declared earlier.
VectorTransform( vPlayerForward, matSkyAngles, vecSkyForward );
VectorTransform( vPlayerRight, matSkyAngles, vecSkyRight );
VectorTransform( vPlayerUp, matSkyAngles, vecSkyUp );
// Normalize them.
VectorNormalize( vecSkyForward );
VectorNormalize( vecSkyRight );
VectorNormalize( vecSkyUp );
// Now do a bit of quaternion magic and apply that to our original angles.
// This works perfectly, so I'm not gonna touch it.
Quaternion quat;
BasisToQuaternion( vecSkyForward, vecSkyRight, vecSkyUp, quat );
QuaternionAngles( quat, angles );
// End of code mostly lifted from projected texture screenspace stuff
// ----------------------------------------------------------------------
// Now just rotate our origin with that matrix.
// We create a copy of the origin since VectorRotate doesn't want in1 to be the same variable as the destination.
VectorRotate(Vector(origin), matSkyAngles, origin);
}
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -454,7 +454,7 @@ private:
#ifdef MAPBASE #ifdef MAPBASE
bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer,
int x, int y, int width, int height, int x, int y, int width, int height,
const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin ); const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, float flLocalPlaneDist );
#endif #endif
// Drawing primitives // Drawing primitives

View File

@ -22,6 +22,7 @@
#include "materialsystem/imaterialvar.h" #include "materialsystem/imaterialvar.h"
#include "mapbase/matchers.h" #include "mapbase/matchers.h"
#include "mapbase/vscript_singletons.h" #include "mapbase/vscript_singletons.h"
#include "mapbase/vscript_vgui.h"
#endif #endif
extern IScriptManager *scriptmanager; extern IScriptManager *scriptmanager;
@ -521,6 +522,9 @@ bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
} }
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
int ScriptScreenWidth();
int ScriptScreenHeight();
static float FrameTime() static float FrameTime()
{ {
return gpGlobals->frametime; return gpGlobals->frametime;
@ -536,27 +540,6 @@ static bool IsWindowedMode()
return engine->IsWindowedMode(); return engine->IsWindowedMode();
} }
int ScreenTransform( const Vector& point, Vector& screen );
//-----------------------------------------------------------------------------
// Input array [x,y], set normalised screen space pos. Return true if on screen
//-----------------------------------------------------------------------------
static bool ScriptScreenTransform( const Vector &pos, HSCRIPT hArray )
{
if ( g_pScriptVM->GetNumTableEntries(hArray) >= 2 )
{
Vector v;
bool r = ScreenTransform( pos, v );
float x = 0.5f * ( 1.0f + v[0] );
float y = 0.5f * ( 1.0f - v[1] );
g_pScriptVM->SetValue( hArray, ScriptVariant_t(0), x );
g_pScriptVM->SetValue( hArray, 1, y );
return !r;
}
return false;
}
// Creates a client-side prop // Creates a client-side prop
HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char *pszModelName, int iAnim ) HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char *pszModelName, int iAnim )
{ {
@ -657,10 +640,9 @@ bool VScriptClientInit()
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the client in the last frame" ); ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the client in the last frame" );
ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" ); ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" );
ScriptRegisterFunction( g_pScriptVM, ScreenWidth, "Width of the screen in pixels" ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenWidth, "ScreenWidth", "Width of the screen in pixels" );
ScriptRegisterFunction( g_pScriptVM, ScreenHeight, "Height of the screen in pixels" ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenHeight, "ScreenHeight", "Height of the screen in pixels" );
ScriptRegisterFunction( g_pScriptVM, IsWindowedMode, "" ); ScriptRegisterFunction( g_pScriptVM, IsWindowedMode, "" );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenTransform, "ScreenTransform", "Get the x & y positions of a world position in screen space. Returns true if it's onscreen" );
ScriptRegisterFunction( g_pScriptVM, MainViewOrigin, "" ); ScriptRegisterFunction( g_pScriptVM, MainViewOrigin, "" );
ScriptRegisterFunction( g_pScriptVM, MainViewAngles, "" ); ScriptRegisterFunction( g_pScriptVM, MainViewAngles, "" );
@ -695,6 +677,7 @@ bool VScriptClientInit()
RegisterSharedScriptConstants(); RegisterSharedScriptConstants();
RegisterSharedScriptFunctions(); RegisterSharedScriptFunctions();
RegisterScriptVGUI();
#else #else
//g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" ); //g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
#endif #endif

View File

@ -2025,7 +2025,8 @@ void CResponseSystem::ParseInclude( CStringPool &includedFiles )
if (len+1 != strlen(scriptfile)) if (len+1 != strlen(scriptfile))
{ {
Q_snprintf(includefile, sizeof(includefile), "%s/%s", includefile, token); Q_strncat( includefile, "/", sizeof( includefile ) );
Q_strncat( includefile, token, sizeof( includefile ) );
} }
else else
includefile[0] = '\0'; includefile[0] = '\0';

View File

@ -2462,6 +2462,32 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED ); ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED ); ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED ); ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_RELOAD_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW );
ADD_ACTIVITY_TO_SR( ACT_RELOAD_DUAL_PISTOLS_LOW );
ADD_ACTIVITY_TO_SR( ACT_COVER_DUAL_PISTOLS_LOW );
ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_DUAL_PISTOLS_LOW );
ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS_RELAXED );
ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS_RELAXED );
ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS_RELAXED );
ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED );
ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED );
#endif #endif
#if EXPANDED_NAVIGATION_ACTIVITIES #if EXPANDED_NAVIGATION_ACTIVITIES
@ -2507,6 +2533,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_HMG1_MED ); ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_HMG1_MED );
ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SNIPER_RIFLE_MED ); ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SNIPER_RIFLE_MED );
ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED ); ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED );
ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_DUAL_PISTOLS_MED );
ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS_MED );
#endif #endif
ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_R ); ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_R );
@ -2620,6 +2648,16 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE ); ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE ); ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SNIPER_RIFLE ); ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_DUAL_PISTOLS );
#endif #endif
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_USE ); ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_USE );

View File

@ -98,6 +98,7 @@
#ifdef MAPBASE #ifdef MAPBASE
#include "mapbase/matchers.h" #include "mapbase/matchers.h"
#include "items.h" #include "items.h"
#include "point_camera.h"
#endif #endif
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
@ -4301,6 +4302,12 @@ bool CAI_BaseNPC::CheckPVSCondition()
{ {
bool bInPVS = ( UTIL_FindClientInPVS( edict() ) != NULL ) || (UTIL_ClientPVSIsExpanded() && UTIL_FindClientInVisibilityPVS( edict() )); bool bInPVS = ( UTIL_FindClientInPVS( edict() ) != NULL ) || (UTIL_ClientPVSIsExpanded() && UTIL_FindClientInVisibilityPVS( edict() ));
#ifdef MAPBASE
// We can be in a player's PVS if there is an active point_camera nearby (fixes issues with choreo)
if (!bInPVS && UTIL_FindRTCameraInEntityPVS( edict() ))
bInPVS = true;
#endif
if ( bInPVS ) if ( bInPVS )
SetCondition( COND_IN_PVS ); SetCondition( COND_IN_PVS );
else else

View File

@ -2930,9 +2930,9 @@ void CBaseAnimating::InvalidateBoneCache( void )
bool CBaseAnimating::TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr ) bool CBaseAnimating::TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
{ {
// Return a special case for scaled physics objects // Return a special case for scaled physics objects
if ( GetModelScale() != 1.0f ) IPhysicsObject *pPhysObject = VPhysicsGetObject();
if ( GetModelScale() != 1.0f && pPhysObject )
{ {
IPhysicsObject *pPhysObject = VPhysicsGetObject();
Vector vecPosition; Vector vecPosition;
QAngle vecAngles; QAngle vecAngles;
pPhysObject->GetPosition( &vecPosition, &vecAngles ); pPhysObject->GetPosition( &vecPosition, &vecAngles );

View File

@ -4228,7 +4228,7 @@ void CBaseCombatCharacter::InputPickupWeaponInstant( inputdata_t &inputdata )
} }
else else
{ {
Warning("%s received PickupWeaponInstant with invalid entity %s\n", GetDebugName(), inputdata.value.Entity() ? "null" : inputdata.value.Entity()->GetDebugName()); Warning("%s received PickupWeaponInstant with invalid entity %s\n", GetDebugName(), inputdata.value.Entity() ? inputdata.value.Entity()->GetDebugName() : "<<null>>");
} }
} }

View File

@ -50,6 +50,7 @@ BEGIN_DATADESC( CEnvProjectedTexture )
DEFINE_FIELD( m_flLinearAtten, FIELD_FLOAT ), DEFINE_FIELD( m_flLinearAtten, FIELD_FLOAT ),
DEFINE_FIELD( m_flQuadraticAtten, FIELD_FLOAT ), DEFINE_FIELD( m_flQuadraticAtten, FIELD_FLOAT ),
DEFINE_KEYFIELD( m_flShadowAtten, FIELD_FLOAT, "shadowatten" ), DEFINE_KEYFIELD( m_flShadowAtten, FIELD_FLOAT, "shadowatten" ),
DEFINE_KEYFIELD( m_flShadowFilter, FIELD_FLOAT, "shadowfilter" ),
#endif #endif
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
@ -77,6 +78,7 @@ BEGIN_DATADESC( CEnvProjectedTexture )
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLinear", InputSetLinear ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLinear", InputSetLinear ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetConstant", InputSetConstant ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetConstant", InputSetConstant ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetShadowAtten", InputSetShadowAtten ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetShadowAtten", InputSetShadowAtten ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFilter", InputSetFilter ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZ", InputSetNearZ ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZ", InputSetNearZ ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarZ", InputSetFarZ ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarZ", InputSetFarZ ),
DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOn", InputAlwaysDrawOn ), DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOn", InputAlwaysDrawOn ),
@ -116,6 +118,7 @@ IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture )
SendPropFloat( SENDINFO( m_flLinearAtten ) ), SendPropFloat( SENDINFO( m_flLinearAtten ) ),
SendPropFloat( SENDINFO( m_flQuadraticAtten ) ), SendPropFloat( SENDINFO( m_flQuadraticAtten ) ),
SendPropFloat( SENDINFO( m_flShadowAtten ) ), SendPropFloat( SENDINFO( m_flShadowAtten ) ),
SendPropFloat( SENDINFO( m_flShadowFilter ) ),
SendPropBool( SENDINFO( m_bAlwaysDraw ) ), SendPropBool( SENDINFO( m_bAlwaysDraw ) ),
// Not needed on the client right now, change when it actually is needed // Not needed on the client right now, change when it actually is needed
@ -158,6 +161,7 @@ CEnvProjectedTexture::CEnvProjectedTexture( void )
m_flLinearAtten = 100.0f; m_flLinearAtten = 100.0f;
m_flConstantAtten = 0.0f; m_flConstantAtten = 0.0f;
m_flShadowAtten = 0.0f; m_flShadowAtten = 0.0f;
m_flShadowFilter = 0.5f;
#endif #endif
} }
@ -316,6 +320,11 @@ void CEnvProjectedTexture::InputSetHorFOV( inputdata_t &inputdata )
{ {
m_flLightHorFOV = inputdata.value.Float(); m_flLightHorFOV = inputdata.value.Float();
} }
void CEnvProjectedTexture::InputSetFilter( inputdata_t &inputdata )
{
m_flShadowFilter = inputdata.value.Float();
}
#endif #endif
void CEnvProjectedTexture::InputSetTarget( inputdata_t &inputdata ) void CEnvProjectedTexture::InputSetTarget( inputdata_t &inputdata )

View File

@ -64,6 +64,7 @@ public:
void InputAlwaysDrawOff( inputdata_t &inputdata ) { m_bAlwaysDraw = false; } void InputAlwaysDrawOff( inputdata_t &inputdata ) { m_bAlwaysDraw = false; }
void InputStopFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = true; } void InputStopFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = true; }
void InputStartFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = false; } void InputStartFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = false; }
void InputSetFilter( inputdata_t &inputdata );
// Corrects keyvalue/input attenuation for internal FlashlightEffect_t attenuation. // Corrects keyvalue/input attenuation for internal FlashlightEffect_t attenuation.
float CorrectConstantAtten( float fl ) { return fl * 0.5f; } float CorrectConstantAtten( float fl ) { return fl * 0.5f; }
@ -105,6 +106,8 @@ private:
CNetworkVar( float, m_flQuadraticAtten ); CNetworkVar( float, m_flQuadraticAtten );
CNetworkVar( float, m_flShadowAtten ); CNetworkVar( float, m_flShadowAtten );
CNetworkVar( float, m_flShadowFilter );
CNetworkVar( bool, m_bAlwaysDraw ); CNetworkVar( bool, m_bAlwaysDraw );
// 1 = New projected texture // 1 = New projected texture

View File

@ -1393,7 +1393,8 @@ Activity CHL2_Player::Weapon_TranslateActivity( Activity baseAct, bool *pRequire
#if EXPANDED_HL2DM_ACTIVITIES #if EXPANDED_HL2DM_ACTIVITIES
// +USE activities // +USE activities
if ( m_hUseEntity && player_use_anim_enabled.GetBool() ) // HACKHACK: Make sure m_hUseEntity is a pickup controller first
if ( m_hUseEntity && m_hUseEntity->ClassMatches("player_pickup") && player_use_anim_enabled.GetBool())
{ {
CBaseEntity* pHeldEnt = GetPlayerHeldEntity( this ); CBaseEntity* pHeldEnt = GetPlayerHeldEntity( this );
float flMass = pHeldEnt ? float flMass = pHeldEnt ?

View File

@ -999,7 +999,11 @@ void CNPC_CombineDropship::Spawn( void )
IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject();
if ( pPhysicsObject ) if ( pPhysicsObject )
{ {
#ifdef MAPBASE
pPhysicsObject->SetShadow( 1e4, 1e4, true, true ); // (allowing physics movement and rotation)
#else
pPhysicsObject->SetShadow( 1e4, 1e4, false, false ); pPhysicsObject->SetShadow( 1e4, 1e4, false, false );
#endif
} }
m_hContainer->SetParent(this, 0); m_hContainer->SetParent(this, 0);

View File

@ -3548,7 +3548,11 @@ Activity CNPC_MetroPolice::NPC_TranslateActivity( Activity newActivity )
// If we're shoving, see if we should be more forceful in doing so // If we're shoving, see if we should be more forceful in doing so
if ( newActivity == ACT_PUSH_PLAYER ) if ( newActivity == ACT_PUSH_PLAYER )
{ {
#ifdef MAPBASE
if ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS && Weapon_TranslateActivity( ACT_MELEE_ATTACK1, NULL ) == ACT_MELEE_ATTACK_SWING )
#else
if ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS ) if ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS )
#endif
return ACT_MELEE_ATTACK1; return ACT_MELEE_ATTACK1;
} }

View File

@ -940,6 +940,14 @@ void CProtoSniper::OnScheduleChange( void )
{ {
LaserOff(); LaserOff();
#ifdef MAPBASE
if ( m_bKilledPlayer && HasCondition( COND_SEE_PLAYER ) )
{
// IMPOSSIBLE! (possible when SP respawn is enabled)
m_bKilledPlayer = false;
}
#endif
BaseClass::OnScheduleChange(); BaseClass::OnScheduleChange();
} }
@ -3439,6 +3447,18 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper )
//========================================================= //=========================================================
//========================================================= //=========================================================
#ifdef MAPBASE
DEFINE_SCHEDULE
(
SCHED_PSNIPER_PLAYER_DEAD,
" Tasks"
" TASK_SNIPER_PLAYER_DEAD 0"
" "
" Interrupts"
" COND_SEE_PLAYER"
)
#else
DEFINE_SCHEDULE DEFINE_SCHEDULE
( (
SCHED_PSNIPER_PLAYER_DEAD, SCHED_PSNIPER_PLAYER_DEAD,
@ -3448,6 +3468,7 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper )
" " " "
" Interrupts" " Interrupts"
) )
#endif
AI_END_CUSTOM_NPC() AI_END_CUSTOM_NPC()

View File

@ -76,7 +76,7 @@ public:
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#ifdef MAPBSAE #ifdef MAPBASE
virtual acttable_t *GetBackupActivityList() { return GetAR2Acttable(); } virtual acttable_t *GetBackupActivityList() { return GetAR2Acttable(); }
virtual int GetBackupActivityListCount() { return GetAR2ActtableCount(); } virtual int GetBackupActivityListCount() { return GetAR2ActtableCount(); }
#endif #endif

View File

@ -4385,7 +4385,7 @@ void CMathClamp::ClampValue(variant_t var, inputdata_t *inputdata)
{ {
// Don't convert up here in case of invalid type // Don't convert up here in case of invalid type
int nBounds; int nBounds = 0;
switch (var.FieldType()) switch (var.FieldType())
{ {

View File

@ -31,6 +31,7 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CParticleSystem, DT_ParticleSystem)
SendPropFloat( SENDINFO(m_flStartTime) ), SendPropFloat( SENDINFO(m_flStartTime) ),
SendPropArray3( SENDINFO_ARRAY3(m_hControlPointEnts), SendPropEHandle( SENDINFO_ARRAY(m_hControlPointEnts) ) ), SendPropArray3( SENDINFO_ARRAY3(m_hControlPointEnts), SendPropEHandle( SENDINFO_ARRAY(m_hControlPointEnts) ) ),
SendPropArray3( SENDINFO_ARRAY3(m_vControlPointVecs), SendPropVector( SENDINFO_ARRAY(m_vControlPointVecs) ) ),
SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ), SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ),
SendPropBool( SENDINFO(m_bWeatherEffect) ), SendPropBool( SENDINFO(m_bWeatherEffect) ),
END_SEND_TABLE() END_SEND_TABLE()
@ -131,6 +132,7 @@ BEGIN_DATADESC( CParticleSystem )
END_DATADESC() END_DATADESC()
LINK_ENTITY_TO_CLASS( info_particle_system, CParticleSystem ); LINK_ENTITY_TO_CLASS( info_particle_system, CParticleSystem );
LINK_ENTITY_TO_CLASS( info_particle_system_coordinate, CParticleSystemCoordinate );
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: // Purpose:
@ -260,17 +262,28 @@ void CParticleSystem::ReadControlPointEnts( void )
{ {
for ( int i = 0 ; i < kMAXCONTROLPOINTS; ++i ) for ( int i = 0 ; i < kMAXCONTROLPOINTS; ++i )
{ {
if ( m_iszControlPointNames[i] == NULL_STRING ) if (UsesCoordinates())
continue;
CBaseEntity *pPointEnt = gEntList.FindEntityGeneric( NULL, STRING( m_iszControlPointNames[i] ), this );
Assert( pPointEnt != NULL );
if ( pPointEnt == NULL )
{ {
Warning("Particle system %s could not find control point entity (%s)\n", GetEntityName().ToCStr(), m_iszControlPointNames[i].ToCStr() ); Vector vecCoords;
continue; // cast str to vector, add vector to array
const char* pszVector = STRING(m_iszControlPointNames[i]);
UTIL_StringToVector(vecCoords.Base(), pszVector);
m_vControlPointVecs.Set(i, vecCoords);
} }
else
{
if ( m_iszControlPointNames[i] == NULL_STRING )
continue;
m_hControlPointEnts.Set( i, pPointEnt ); CBaseEntity *pPointEnt = gEntList.FindEntityGeneric( NULL, STRING( m_iszControlPointNames[i] ), this );
Assert( pPointEnt != NULL );
if ( pPointEnt == NULL )
{
Warning("Particle system %s could not find control point entity (%s)\n", GetEntityName().ToCStr(), m_iszControlPointNames[i].ToCStr() );
continue;
}
m_hControlPointEnts.Set( i, pPointEnt );
}
} }
} }

View File

@ -41,6 +41,8 @@ public:
enum { kMAXCONTROLPOINTS = 63 }; ///< actually one less than the total number of cpoints since 0 is assumed to be me enum { kMAXCONTROLPOINTS = 63 }; ///< actually one less than the total number of cpoints since 0 is assumed to be me
virtual bool UsesCoordinates( void ) { return false; }
protected: protected:
/// Load up and resolve the entities that are supposed to be the control points /// Load up and resolve the entities that are supposed to be the control points
@ -58,8 +60,19 @@ protected:
string_t m_iszControlPointNames[kMAXCONTROLPOINTS]; string_t m_iszControlPointNames[kMAXCONTROLPOINTS];
CNetworkArray( EHANDLE, m_hControlPointEnts, kMAXCONTROLPOINTS ); CNetworkArray( EHANDLE, m_hControlPointEnts, kMAXCONTROLPOINTS );
CNetworkArray( Vector, m_vControlPointVecs, kMAXCONTROLPOINTS );
CNetworkArray( unsigned char, m_iControlPointParents, kMAXCONTROLPOINTS ); CNetworkArray( unsigned char, m_iControlPointParents, kMAXCONTROLPOINTS );
CNetworkVar( bool, m_bWeatherEffect ); CNetworkVar( bool, m_bWeatherEffect );
}; };
//-----------------------------------------------------------------------------
// Purpose: An entity that spawns and controls a particle system using coordinates.
//-----------------------------------------------------------------------------
class CParticleSystemCoordinate : public CParticleSystem
{
DECLARE_CLASS( CParticleSystemCoordinate, CParticleSystem );
public:
virtual bool UsesCoordinates( void ) { return true; }
};
#endif // PARTICLE_SYSTEM_H #endif // PARTICLE_SYSTEM_H

View File

@ -645,8 +645,14 @@ void CBasePlayer::CreateHandModel(int index, int iOtherVm)
{ {
Assert(index >= 0 && index < MAX_VIEWMODELS && iOtherVm >= 0 && iOtherVm < MAX_VIEWMODELS ); Assert(index >= 0 && index < MAX_VIEWMODELS && iOtherVm >= 0 && iOtherVm < MAX_VIEWMODELS );
if (GetViewModel(index)) if (GetViewModel( index ))
{
// This can happen if the player respawns
// Don't draw unless we're already using a hands weapon
if ( !GetActiveWeapon() || !GetActiveWeapon()->UsesHands() )
GetViewModel( index )->AddEffects( EF_NODRAW );
return; return;
}
CBaseViewModel *vm = (CBaseViewModel *)CreateEntityByName("hand_viewmodel"); CBaseViewModel *vm = (CBaseViewModel *)CreateEntityByName("hand_viewmodel");
if (vm) if (vm)
@ -1719,6 +1725,15 @@ void CBasePlayer::RemoveAllItems( bool removeSuit )
RemoveAllWeapons(); RemoveAllWeapons();
RemoveAllAmmo(); RemoveAllAmmo();
#ifdef MAPBASE
// Hide hand viewmodel
CBaseViewModel *vm = GetViewModel( 1 );
if ( vm )
{
vm->AddEffects( EF_NODRAW );
}
#endif
if ( removeSuit ) if ( removeSuit )
{ {
RemoveSuit(); RemoveSuit();

View File

@ -28,6 +28,58 @@ CPointCamera* GetPointCameraList()
return g_PointCameraList.m_pClassList; return g_PointCameraList.m_pClassList;
} }
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose: Returns true if a camera is in the PVS of the specified entity
//-----------------------------------------------------------------------------
edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict )
{
CBaseEntity *pe = GetContainingEntity( pEdict );
if ( !pe )
return NULL;
bool bGotPVS = false;
Vector org;
static byte pvs[ MAX_MAP_CLUSTERS/8 ];
static int pvssize = sizeof( pvs );
for ( CPointCamera *pCameraEnt = GetPointCameraList(); pCameraEnt != NULL; pCameraEnt = pCameraEnt->m_pNext )
{
if (!pCameraEnt->IsActive())
continue;
if (!bGotPVS)
{
// Getting the PVS during the loop like this makes sure we only get the PVS if there's actually an active camera in the level
org = pe->EyePosition();
int clusterIndex = engine->GetClusterForOrigin( org );
Assert( clusterIndex >= 0 );
engine->GetPVSForCluster( clusterIndex, pvssize, pvs );
bGotPVS = true;
}
Vector vecCameraEye = pCameraEnt->EyePosition();
Vector vecCameraDirection;
pCameraEnt->GetVectors( &vecCameraDirection, NULL, NULL );
Vector los = (org - vecCameraEye);
float flDot = DotProduct( los, vecCameraDirection );
// Make sure we're in the camera's FOV before checking PVS
if ( flDot <= cos( DEG2RAD( pCameraEnt->GetFOV() / 2 ) ) )
continue;
if ( engine->CheckOriginInPVS( vecCameraEye, pvs, pvssize ) )
{
return pCameraEnt->edict();
}
}
return NULL;
}
#endif
// These are already built into CBaseEntity // These are already built into CBaseEntity
// DEFINE_KEYFIELD( m_iName, FIELD_STRING, "targetname" ), // DEFINE_KEYFIELD( m_iName, FIELD_STRING, "targetname" ),
// DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ), // DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ),

View File

@ -42,6 +42,7 @@ public:
void InputSetRenderTarget( inputdata_t &inputdata ) { m_iszRenderTarget = inputdata.value.StringID(); } void InputSetRenderTarget( inputdata_t &inputdata ) { m_iszRenderTarget = inputdata.value.StringID(); }
float GetFOV() const { return m_FOV; } float GetFOV() const { return m_FOV; }
bool IsActive() const { return m_bIsOn; }
#endif #endif
private: private:
@ -117,4 +118,8 @@ private:
#endif #endif
CPointCamera *GetPointCameraList(); CPointCamera *GetPointCameraList();
#ifdef MAPBASE
edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict );
#endif
#endif // CAMERA_H #endif // CAMERA_H

View File

@ -2283,11 +2283,7 @@ bool CDynamicProp::TestCollision( const Ray_t &ray, unsigned int mask, trace_t&
} }
} }
} }
#ifdef MAPBASE // From Alien Swarm SDK
return BaseClass::TestCollision( ray, mask, trace );
#else
return false; return false;
#endif
} }
@ -2800,7 +2796,7 @@ void CInteractableProp::Precache( void )
// useType - // useType -
// value - // value -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CInteractableProp::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) void CInteractableProp::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{ {
if (m_flCooldownTime > gpGlobals->curtime) if (m_flCooldownTime > gpGlobals->curtime)
return; return;
@ -2808,18 +2804,18 @@ void CInteractableProp::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_
// If we're using +USE mins/maxs, make sure this is being +USE'd from the right place // If we're using +USE mins/maxs, make sure this is being +USE'd from the right place
if (m_vecUseMins.LengthSqr() != 0.0f && m_vecUseMaxs.LengthSqr() != 0.0f) if (m_vecUseMins.LengthSqr() != 0.0f && m_vecUseMaxs.LengthSqr() != 0.0f)
{ {
CBasePlayer *pPlayer = ToBasePlayer( pActivator ); CBasePlayer *pPlayer = ToBasePlayer(pActivator);
if (pPlayer) if (pPlayer)
{ {
Vector forward; Vector forward;
pPlayer->EyeVectors( &forward, NULL, NULL ); pPlayer->EyeVectors(&forward, NULL, NULL);
// This might be a little convoluted and/or seem needlessly expensive, but I couldn't figure out any better way to do this. // This might be a little convoluted and/or seem needlessly expensive, but I couldn't figure out any better way to do this.
// TOOD: Can we calculate a box in local space instead of world space? // TOOD: Can we calculate a box in local space instead of world space?
Vector vecWorldMins, vecWorldMaxs; Vector vecWorldMins, vecWorldMaxs;
RotateAABB( EntityToWorldTransform(), m_vecUseMins, m_vecUseMaxs, vecWorldMins, vecWorldMaxs ); RotateAABB(EntityToWorldTransform(), m_vecUseMins, m_vecUseMaxs, vecWorldMins, vecWorldMaxs);
TransformAABB( EntityToWorldTransform(), vecWorldMins, vecWorldMaxs, vecWorldMins, vecWorldMaxs ); TransformAABB(EntityToWorldTransform(), vecWorldMins, vecWorldMaxs, vecWorldMins, vecWorldMaxs);
if (!IsBoxIntersectingRay( vecWorldMins, vecWorldMaxs, pPlayer->EyePosition(), forward * 1024 )) if (!IsBoxIntersectingRay(vecWorldMins, vecWorldMaxs, pPlayer->EyePosition(), forward * 1024))
{ {
// Reject this +USE if it's not in our box // Reject this +USE if it's not in our box
DevMsg("Outside of +USE box\n"); DevMsg("Outside of +USE box\n");
@ -2832,28 +2828,36 @@ void CInteractableProp::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_
if (m_bLocked) if (m_bLocked)
{ {
m_OnLockedUse.FireOutput( pActivator, this ); m_OnLockedUse.FireOutput(pActivator, this);
EmitSound(STRING(m_iszLockedSound)); EmitSound(STRING(m_iszLockedSound));
nSequence = LookupSequence( STRING( m_iszLockedSequence ) ); nSequence = LookupSequence(STRING(m_iszLockedSequence));
m_iCurSequence = INTERACTSEQ_LOCKED; m_iCurSequence = INTERACTSEQ_LOCKED;
} }
else else
{ {
m_OnPressed.FireOutput( pActivator, this ); m_OnPressed.FireOutput(pActivator, this);
EmitSound(STRING(m_iszPressedSound)); EmitSound(STRING(m_iszPressedSound));
nSequence = LookupSequence( STRING( m_iszInSequence ) ); nSequence = LookupSequence(STRING(m_iszInSequence));
m_iCurSequence = INTERACTSEQ_IN; m_iCurSequence = INTERACTSEQ_IN;
} }
if ( nSequence > ACTIVITY_NOT_AVAILABLE ) if (nSequence > ACTIVITY_NOT_AVAILABLE)
{ {
SetPushSequence(nSequence); SetPushSequence(nSequence);
// We still fire our inherited animation outputs // We still fire our inherited animation outputs
m_pOutputAnimBegun.FireOutput( pActivator, this ); m_pOutputAnimBegun.FireOutput(pActivator, this);
} }
m_flCooldownTime = gpGlobals->curtime + m_flCooldown; if (m_flCooldown == -1 && !m_bLocked){
m_flCooldownTime = FLT_MAX; // yeah we're not going to hit this any time soon
}
else if (m_flCooldown == -1){
m_flCooldownTime = gpGlobals->curtime + 1.0f; // 1s cooldown if locked
}
else{
m_flCooldownTime = gpGlobals->curtime + m_flCooldown;
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -2578,6 +2578,32 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED ); REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED ); REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED ); REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_RELOAD_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW );
REGISTER_SHARED_ACTIVITY( ACT_RELOAD_DUAL_PISTOLS_LOW );
REGISTER_SHARED_ACTIVITY( ACT_COVER_DUAL_PISTOLS_LOW );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_DUAL_PISTOLS_LOW );
REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS_RELAXED );
REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS_RELAXED );
REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS_RELAXED );
REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED );
REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED );
#endif #endif
#if EXPANDED_NAVIGATION_ACTIVITIES #if EXPANDED_NAVIGATION_ACTIVITIES
@ -2623,6 +2649,8 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_HMG1_MED ); REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_HMG1_MED );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SNIPER_RIFLE_MED ); REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SNIPER_RIFLE_MED );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED ); REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_DUAL_PISTOLS_MED );
REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS_MED );
#endif #endif
REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_R ); REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_R );
@ -2736,6 +2764,16 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE ); REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE ); REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SNIPER_RIFLE ); REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_DUAL_PISTOLS );
#endif #endif
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_USE ); REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_USE );

View File

@ -45,7 +45,7 @@
// This enables a bunch of new activities for unused Half-Life 2 weapons, particularly those which exist in the SDK, but are deactivated by default. // This enables a bunch of new activities for unused Half-Life 2 weapons, particularly those which exist in the SDK, but are deactivated by default.
// This essentially just means mods which restore those weapons have the option of using custom activities for them. // This essentially just means mods which restore those weapons have the option of using custom activities for them.
// Mapbase's backup activity system would allow them to fall back to other weapons if the relevant activities do not exist. // Mapbase's backup activity system would allow them to fall back to other weapons if the relevant activities do not exist.
// Also includes activity names for the "AR3" and "SMG3", which were never used in HL2, but may be useful when additional animation sets are needed. // Also includes activity names for "AR3", "SMG3", and "DUAL_PISTOLS", which were never used in HL2, but may be useful when additional animation sets are needed.
#define EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES 0 #define EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES 0
// EXPANDED NAVIGATION ACTIVITIES // EXPANDED NAVIGATION ACTIVITIES
@ -2478,6 +2478,33 @@ typedef enum
ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED, ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED,
ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED, ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED,
ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED, ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED,
// Dual Pistols
ACT_IDLE_DUAL_PISTOLS,
ACT_IDLE_ANGRY_DUAL_PISTOLS,
ACT_WALK_DUAL_PISTOLS,
ACT_RUN_DUAL_PISTOLS,
ACT_WALK_AIM_DUAL_PISTOLS,
ACT_RUN_AIM_DUAL_PISTOLS,
ACT_RANGE_ATTACK_DUAL_PISTOLS,
ACT_RELOAD_DUAL_PISTOLS,
ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW,
ACT_RELOAD_DUAL_PISTOLS_LOW,
ACT_COVER_DUAL_PISTOLS_LOW,
ACT_RANGE_AIM_DUAL_PISTOLS_LOW,
ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS,
ACT_GESTURE_RELOAD_DUAL_PISTOLS,
ACT_IDLE_DUAL_PISTOLS_RELAXED,
ACT_IDLE_DUAL_PISTOLS_STIMULATED,
ACT_WALK_DUAL_PISTOLS_RELAXED,
ACT_RUN_DUAL_PISTOLS_RELAXED,
ACT_WALK_DUAL_PISTOLS_STIMULATED,
ACT_RUN_DUAL_PISTOLS_STIMULATED,
ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED,
ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED,
ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED,
#endif #endif
#if EXPANDED_NAVIGATION_ACTIVITIES #if EXPANDED_NAVIGATION_ACTIVITIES
@ -2525,6 +2552,8 @@ typedef enum
ACT_RANGE_ATTACK_HMG1_MED, ACT_RANGE_ATTACK_HMG1_MED,
ACT_RANGE_AIM_SNIPER_RIFLE_MED, ACT_RANGE_AIM_SNIPER_RIFLE_MED,
ACT_RANGE_ATTACK_SNIPER_RIFLE_MED, ACT_RANGE_ATTACK_SNIPER_RIFLE_MED,
ACT_RANGE_AIM_DUAL_PISTOLS_MED,
ACT_RANGE_ATTACK_DUAL_PISTOLS_MED,
#endif #endif
// Wall Cover (for use in custom cover hints) // Wall Cover (for use in custom cover hints)
@ -2640,6 +2669,16 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE,
ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE, ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE,
ACT_HL2MP_JUMP_SNIPER_RIFLE, ACT_HL2MP_JUMP_SNIPER_RIFLE,
ACT_HL2MP_IDLE_DUAL_PISTOLS,
ACT_HL2MP_RUN_DUAL_PISTOLS,
ACT_HL2MP_WALK_DUAL_PISTOLS,
ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS,
ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS,
ACT_HL2MP_JUMP_DUAL_PISTOLS,
#endif #endif
ACT_HL2MP_IDLE_USE, ACT_HL2MP_IDLE_USE,

View File

@ -35,7 +35,6 @@
#include "tier0/memdbgon.h" #include "tier0/memdbgon.h"
#define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt" #define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt"
#define GENERIC_MANIFEST_FILE_ADDON "scripts/mapbase_default_manifest_addon.txt"
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
#define AUTOLOADED_MANIFEST_FILE VarArgs("maps/%s_manifest.txt", g_MapName) #define AUTOLOADED_MANIFEST_FILE VarArgs("maps/%s_manifest.txt", g_MapName)
@ -53,8 +52,6 @@ ConVar mapbase_load_default_manifest("mapbase_load_default_manifest", "1", FCVAR
// This constant should change with each Mapbase update // This constant should change with each Mapbase update
ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" ); ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" );
ConVar mapbase_load_addon_manifest( "mapbase_load_addon_manifest", "0", FCVAR_NONE, "Allows manifests from \"addon\" path IDs to be loaded." );
ConVar mapbase_flush_talker("mapbase_flush_talker", "1", FCVAR_NONE, "Normally, when a map with custom talker files is unloaded, the response system resets to rid itself of the custom file(s). Turn this convar off to prevent that from happening."); ConVar mapbase_flush_talker("mapbase_flush_talker", "1", FCVAR_NONE, "Normally, when a map with custom talker files is unloaded, the response system resets to rid itself of the custom file(s). Turn this convar off to prevent that from happening.");
extern void MapbaseGameLog_Init(); extern void MapbaseGameLog_Init();
@ -70,8 +67,6 @@ static bool g_bMapContainsCustomTalker;
// This constant should change with each Mapbase update // This constant should change with each Mapbase update
ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" ); ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" );
ConVar mapbase_load_addon_manifest( "mapbase_load_addon_manifest_client", "0", FCVAR_NONE, "Allows manifests from \"addon\" path IDs to be loaded on the client." );
// This is from the vgui_controls library // This is from the vgui_controls library
extern vgui::HScheme g_iCustomClientSchemeOverride; extern vgui::HScheme g_iCustomClientSchemeOverride;
@ -276,37 +271,6 @@ public:
ParseGenericManifest(); ParseGenericManifest();
} }
// Load addon manifests if we should
if (mapbase_load_addon_manifest.GetBool())
{
char searchPaths[4096];
filesystem->GetSearchPath( "ADDON", true, searchPaths, sizeof( searchPaths ) );
for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) )
{
char pathName[MAX_PATH];
V_StripTrailingSlash( path );
V_FileBase( path, pathName, sizeof( pathName ) );
KeyValues *pKV = new KeyValues( "DefaultAddonManifest" );
char manifestName[MAX_PATH];
V_snprintf( manifestName, sizeof( manifestName ), "%s_mapbase_manifest.txt", pathName );
if (filesystem->FileExists( manifestName, "ADDON" ))
{
if (pKV->LoadFromFile( filesystem, manifestName ))
AddManifestFile( pKV, pathName, false );
}
else
{
if (pKV->LoadFromFile( filesystem, GENERIC_MANIFEST_FILE_ADDON ))
AddManifestFile( pKV, pathName, true );
}
pKV->deleteThis();
}
}
#ifdef GAME_DLL #ifdef GAME_DLL
MapbaseGameLog_Init(); MapbaseGameLog_Init();
#endif #endif

View File

@ -938,6 +938,26 @@ bool ScriptIsClient()
#endif #endif
} }
bool ScriptIsWindows()
{
return IsWindows();
}
bool ScriptIsLinux()
{
return IsLinux();
}
bool ScriptIsOSX()
{
return IsOSX();
}
bool ScriptIsPosix()
{
return IsPosix();
}
// Notification printing on the right edge of the screen // Notification printing on the right edge of the screen
void NPrint( int pos, const char* fmt ) void NPrint( int pos, const char* fmt )
{ {
@ -1077,5 +1097,10 @@ void RegisterSharedScriptFunctions()
ScriptRegisterFunction( g_pScriptVM, GetFrameCount, "Absolute frame counter" ); ScriptRegisterFunction( g_pScriptVM, GetFrameCount, "Absolute frame counter" );
//ScriptRegisterFunction( g_pScriptVM, GetTickCount, "Simulation ticks" ); //ScriptRegisterFunction( g_pScriptVM, GetTickCount, "Simulation ticks" );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsWindows, "IsWindows", "Returns true if the game is being run on a Windows machine." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsLinux, "IsLinux", "Returns true if the game is being run on a Linux machine." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsOSX, "IsOSX", "Returns true if the game is being run on an OSX machine." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsPosix, "IsPosix", "Returns true if the game is being run on a Posix machine." );
RegisterScriptSingletons(); RegisterScriptSingletons();
} }

View File

@ -740,7 +740,11 @@ void CScriptGameEventListener::StopListeningForEvent()
#ifdef _DEBUG #ifdef _DEBUG
// Event listeners are iterated forwards in the game event manager, // Event listeners are iterated forwards in the game event manager,
// removing while iterating will cause it to skip one listener. // removing while iterating will cause it to skip one listener.
// This could be prevented by writing a custom game event manager. //
// Fix this in engine without altering any behaviour by
// changing event exeuction order to tail->head,
// changing listener removal to tail->head,
// changing listener addition to head
if ( m_nEventTick == gpGlobals->tickcount ) if ( m_nEventTick == gpGlobals->tickcount )
{ {
Warning("CScriptGameEventListener stopped in the same frame it was fired. This will break other event listeners!\n"); Warning("CScriptGameEventListener stopped in the same frame it was fired. This will break other event listeners!\n");
@ -1273,9 +1277,11 @@ CNetMsgScriptHelper *g_ScriptNetMsg = &scriptnetmsg;
#ifdef _DEBUG #ifdef _DEBUG
#ifdef GAME_DLL #ifdef GAME_DLL
#define DebugNetMsg( l, ... ) do { extern ConVar developer; if (developer.GetInt() >= l) ConColorMsg( Color(100, 225, 255, 255), __VA_ARGS__ ); } while (0); ConVar script_net_debug("script_net_debug", "0");
#define DebugNetMsg( l, ... ) do { if (script_net_debug.GetInt() >= l) ConColorMsg( Color(100, 225, 255, 255), __VA_ARGS__ ); } while (0);
#else #else
#define DebugNetMsg( l, ... ) do { extern ConVar developer; if (developer.GetInt() >= l) ConColorMsg( Color(100, 225, 175, 255), __VA_ARGS__ ); } while (0); ConVar script_net_debug("script_net_debug_client", "0");
#define DebugNetMsg( l, ... ) do { if (script_net_debug.GetInt() >= l) ConColorMsg( Color(100, 225, 175, 255), __VA_ARGS__ ); } while (0);
#endif #endif
#define DebugWarning(...) Warning( __VA_ARGS__ ) #define DebugWarning(...) Warning( __VA_ARGS__ )
#else #else
@ -1424,7 +1430,7 @@ void CNetMsgScriptHelper::ReceiveMessage( bf_read &msg )
m_MsgIn.StartReading( msg.m_pData, msg.m_nDataBytes ); m_MsgIn.StartReading( msg.m_pData, msg.m_nDataBytes );
#endif #endif
DebugNetMsg( 2, DLL_LOC_STR " " __FUNCTION__ "()\n" ); DebugNetMsg( 2, DLL_LOC_STR " %s()\n", __FUNCTION__ );
// Don't do anything if there's no VM here. This can happen if a message from the server goes to a VM-less client, or vice versa. // Don't do anything if there's no VM here. This can happen if a message from the server goes to a VM-less client, or vice versa.
if ( !g_pScriptVM ) if ( !g_pScriptVM )
@ -1483,7 +1489,7 @@ void CNetMsgScriptHelper::Start( const char *msg )
return; return;
} }
DebugNetMsg( 1, DLL_LOC_STR " " __FUNCTION__ "() [%d]%s\n", Hash( msg ), msg ); DebugNetMsg( 1, DLL_LOC_STR " %s() [%d]%s\n", __FUNCTION__, Hash( msg ), msg );
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
// Client can write multiple messages in a frame before the usercmd is sent, // Client can write multiple messages in a frame before the usercmd is sent,
@ -1519,7 +1525,7 @@ void CNetMsgScriptHelper::Start( const char *msg )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetMsgScriptHelper::Send( HSCRIPT player, bool bReliable ) void CNetMsgScriptHelper::Send( HSCRIPT player, bool bReliable )
{ {
DebugNetMsg( 1, DLL_LOC_STR " " __FUNCTION__ "() size(%d)\n", GetNumBitsWritten() ); DebugNetMsg( 1, DLL_LOC_STR " %s() size(%d)\n", __FUNCTION__, GetNumBitsWritten() );
CBaseEntity *pPlayer = ToEnt(player); CBaseEntity *pPlayer = ToEnt(player);
if ( pPlayer ) if ( pPlayer )
@ -1544,7 +1550,7 @@ void CNetMsgScriptHelper::Send( HSCRIPT player, bool bReliable )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetMsgScriptHelper::Send() void CNetMsgScriptHelper::Send()
{ {
DebugNetMsg( 1, DLL_LOC_STR " " __FUNCTION__ "() size(%d)\n", m_bWriteIgnore ? 0 : GetNumBitsWritten() ); DebugNetMsg( 1, DLL_LOC_STR " %s() size(%d)\n", __FUNCTION__, m_bWriteIgnore ? 0 : GetNumBitsWritten() );
m_bWriteReady = true; m_bWriteReady = true;
} }
@ -1749,8 +1755,8 @@ void CNetMsgScriptHelper::WriteEntity( HSCRIPT hEnt )
{ {
SCRIPT_NETMSG_WRITE_FUNC SCRIPT_NETMSG_WRITE_FUNC
CBaseEntity *p = ToEnt(hEnt); CBaseEntity *p = ToEnt(hEnt);
int i = p ? p->entindex() : -1; int i = p ? p->entindex() : 0;
m_MsgOut.WriteSBitLong( i, MAX_EDICT_BITS ); m_MsgOut.WriteUBitLong( i, MAX_EDICT_BITS );
} }
void CNetMsgScriptHelper::WriteEHandle( HSCRIPT hEnt ) void CNetMsgScriptHelper::WriteEHandle( HSCRIPT hEnt )
@ -1861,7 +1867,11 @@ bool CNetMsgScriptHelper::ReadBool()
HSCRIPT CNetMsgScriptHelper::ReadEntity() HSCRIPT CNetMsgScriptHelper::ReadEntity()
{ {
int index = m_MsgIn_()ReadSBitLong( MAX_EDICT_BITS ); int index = m_MsgIn_()ReadUBitLong( MAX_EDICT_BITS );
if ( !index )
return NULL;
#ifdef GAME_DLL #ifdef GAME_DLL
edict_t *e = INDEXENT(index); edict_t *e = INDEXENT(index);
if ( e && !e->IsFree() ) if ( e && !e->IsFree() )
@ -3232,6 +3242,31 @@ public:
return ret; return ret;
} }
const char *GetCurrentBetaName()
{
if ( !steamapicontext || !steamapicontext->SteamApps() )
return NULL;
static char ret[16];
steamapicontext->SteamApps()->GetCurrentBetaName( ret, sizeof( ret ) );
return ret;
}
#if 0
bool IsSubscribedApp( int nAppID )
{
if ( !steamapicontext || !steamapicontext->SteamApps() )
return false;
return steamapicontext->SteamApps()->BIsSubscribedApp( nAppID );
}
#endif
bool IsAppInstalled( int nAppID )
{
if ( !steamapicontext || !steamapicontext->SteamApps() )
return false;
return steamapicontext->SteamApps()->BIsAppInstalled( nAppID );
}
} g_ScriptSteamAPI; } g_ScriptSteamAPI;
@ -3242,6 +3277,9 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptSteamAPI, "CSteamAPI", SCRIPT_SINGLETON "" )
DEFINE_SCRIPTFUNC( GetCurrentBatteryPower, "Return the amount of battery power left in the current system in % [0..100], 255 for being on AC power" ) DEFINE_SCRIPTFUNC( GetCurrentBatteryPower, "Return the amount of battery power left in the current system in % [0..100], 255 for being on AC power" )
//DEFINE_SCRIPTFUNC( GetIPCountry, "Returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)" ) //DEFINE_SCRIPTFUNC( GetIPCountry, "Returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)" )
DEFINE_SCRIPTFUNC( GetCurrentGameLanguage, "Gets the current language that the user has set as API language code. This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title." ) DEFINE_SCRIPTFUNC( GetCurrentGameLanguage, "Gets the current language that the user has set as API language code. This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title." )
DEFINE_SCRIPTFUNC( GetCurrentBetaName, "Gets the name of the user's current beta branch. In Source SDK Base 2013 Singleplayer, this will usually return 'upcoming'." )
//DEFINE_SCRIPTFUNC( IsSubscribedApp, "Returns true if the user is subscribed to the specified app ID." )
DEFINE_SCRIPTFUNC( IsAppInstalled, "Returns true if the user has the specified app ID installed on their computer." )
END_SCRIPTDESC(); END_SCRIPTDESC();
#endif // !NO_STEAM #endif // !NO_STEAM

View File

@ -62,7 +62,11 @@ HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
{ {
#ifdef MAPBASE_VSCRIPT
CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type (\"%s\", from \"%s\") does not match VM type (\"%s\")\n", pszIncomingExtension, pszScriptName, pszVMExtension );
#else
CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" ); CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" );
#endif
return NULL; return NULL;
} }
@ -187,8 +191,16 @@ HSCRIPT VScriptCompileScriptAbsolute( const char *pszScriptName, bool bWarnMissi
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
{ {
CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" ); // Account for cases where there is no extension and the folder names just have dots (e.g. ".local")
return NULL; if ( strchr( pszIncomingExtension, CORRECT_PATH_SEPARATOR ) )
{
pszIncomingExtension = NULL;
}
else
{
CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type (\"%s\", from \"%s\") does not match VM type (\"%s\")\n", pszIncomingExtension, pszScriptName, pszVMExtension );
return NULL;
}
} }
CFmtStr scriptPath; CFmtStr scriptPath;

Binary file not shown.

View File

@ -225,7 +225,7 @@ BEGIN_VS_SHADER( SDK_DecalModulate_dx9,
SetFlashLightColorFromState( state, pShaderAPI, 28 ); SetFlashLightColorFromState( state, pShaderAPI, 28 );
Assert( state.m_pSpotlightTexture >= 0 && state.m_nSpotlightTextureFrame >= 0 ); Assert( state.m_pSpotlightTexture && state.m_nSpotlightTextureFrame >= 0 );
BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame );
float atten_pos[8]; float atten_pos[8];

View File

@ -1281,8 +1281,8 @@ PLATFORM_INTERFACE bool Is64BitOS();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// General Mapbase version constants compiled into projects for versioning purposes // General Mapbase version constants compiled into projects for versioning purposes
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define MAPBASE_VERSION "7.0" #define MAPBASE_VERSION "7.1"
#define MAPBASE_VER_INT 7000 // For use in #if in a similar fashion to macros like _MSC_VER #define MAPBASE_VER_INT 7100 // For use in #if in a similar fashion to macros like _MSC_VER
#endif #endif

View File

@ -1605,6 +1605,10 @@ typedef CScriptScopeT<> CScriptScope;
#define FOR_EACH_VEC_PTR( vecName, iteratorName ) \ #define FOR_EACH_VEC_PTR( vecName, iteratorName ) \
for ( int iteratorName = 0; iteratorName < (vecName)->Count(); iteratorName++ ) for ( int iteratorName = 0; iteratorName < (vecName)->Count(); iteratorName++ )
//-----------------------------------------------------------------------------
static void __UpdateScriptHooks( HSCRIPT hooksList );
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Keeps track of which events and scopes are hooked without polling this from the script VM on each request. // Keeps track of which events and scopes are hooked without polling this from the script VM on each request.
@ -1654,12 +1658,6 @@ public:
return scopeMap->Find( g_pScriptVM->HScriptToRaw( hScope ) ) != scopeMap->InvalidIndex(); return scopeMap->Find( g_pScriptVM->HScriptToRaw( hScope ) ) != scopeMap->InvalidIndex();
} }
static void __UpdateScriptHooks( HSCRIPT hooksList )
{
extern CScriptHookManager &GetScriptHookManager();
GetScriptHookManager().Update( hooksList );
}
// //
// On VM init, registers script func and caches the hook func. // On VM init, registers script func and caches the hook func.
// //
@ -1843,7 +1841,7 @@ public:
scopemap_t *scopeMap = m_HookList.Element(i); scopemap_t *scopeMap = m_HookList.Element(i);
char *szEvent = m_HookList.Key(i); char *szEvent = m_HookList.Key(i);
Msg( "%s [%x]\n", szEvent, (void*)scopeMap ); Msg( "%s [%p]\n", szEvent, (void*)scopeMap );
Msg( "{\n" ); Msg( "{\n" );
FOR_EACH_MAP_PTR( scopeMap, j ) FOR_EACH_MAP_PTR( scopeMap, j )
@ -1851,7 +1849,7 @@ public:
HScriptRaw hScope = scopeMap->Key(j); HScriptRaw hScope = scopeMap->Key(j);
contextmap_t *contextMap = scopeMap->Element(j); contextmap_t *contextMap = scopeMap->Element(j);
Msg( "\t(0x%X) [%x]\n", hScope, (void*)contextMap ); Msg( "\t(0x%X) [%p]\n", hScope, (void*)contextMap );
Msg( "\t{\n" ); Msg( "\t{\n" );
FOR_EACH_VEC_PTR( contextMap, k ) FOR_EACH_VEC_PTR( contextMap, k )
@ -1876,6 +1874,11 @@ inline CScriptHookManager &GetScriptHookManager()
return g_ScriptHookManager; return g_ScriptHookManager;
} }
static void __UpdateScriptHooks( HSCRIPT hooksList )
{
GetScriptHookManager().Update( hooksList );
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Function bindings allow script functions to run C++ functions. // Function bindings allow script functions to run C++ functions.

View File

@ -1509,7 +1509,8 @@ void CResponseSystem::ParseInclude()
if (len+1 != strlen(scriptfile)) if (len+1 != strlen(scriptfile))
{ {
Q_snprintf(includefile, sizeof(includefile), "%s/%s", includefile, token); Q_strncat( includefile, "/", sizeof( includefile ) );
Q_strncat( includefile, token, sizeof( includefile ) );
} }
else else
includefile[0] = '\0'; includefile[0] = '\0';

View File

@ -28,6 +28,9 @@
#include "utlhash.h" #include "utlhash.h"
#include "UtlSortVector.h" #include "UtlSortVector.h"
#include "convar.h" #include "convar.h"
#ifdef MAPBASE
#include "icommandline.h"
#endif
// memdbgon must be the last include file in a .cpp file!!! // memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h> #include <tier0/memdbgon.h>
@ -2081,6 +2084,28 @@ bool EvaluateConditional( const char *str )
if ( Q_stristr( str, "$POSIX" ) ) if ( Q_stristr( str, "$POSIX" ) )
return IsPosix() ^ bNot; return IsPosix() ^ bNot;
#ifdef MAPBASE
// Custom conditional
switch( str[bNot ? 1 : 0] )
{
case '%':
{
// Look for a cvar
ConVarRef cvar( str + (bNot ? 2 : 1), true );
if (cvar.IsValid())
{
return cvar.GetBool() ^ bNot;
}
} break;
case '-':
{
// Look for a command line param
return (CommandLine()->CheckParm( bNot ? str+1 : str ) != 0) ^ bNot;
} break;
}
#endif
return false; return false;
} }

View File

@ -357,7 +357,12 @@ bool AnimationController::ParseScriptFile(char *pMem, int length)
// get the open brace or a conditional // get the open brace or a conditional
pMem = ParseFile(pMem, token, NULL); pMem = ParseFile(pMem, token, NULL);
#ifdef MAPBASE
// Fixes ! conditionals
if ( Q_stristr( token, "[$" ) || Q_stristr( token, "[!$" ) )
#else
if ( Q_stristr( token, "[$" ) ) if ( Q_stristr( token, "[$" ) )
#endif
{ {
bAccepted = EvaluateConditional( token ); bAccepted = EvaluateConditional( token );
@ -622,7 +627,12 @@ bool AnimationController::ParseScriptFile(char *pMem, int length)
// Look ahead one token for a conditional // Look ahead one token for a conditional
char *peek = ParseFile(pMem, token, NULL); char *peek = ParseFile(pMem, token, NULL);
#ifdef MAPBASE
// Fixes ! conditionals
if ( Q_stristr( token, "[$" ) || Q_stristr( token, "[!$" ) )
#else
if ( Q_stristr( token, "[$" ) ) if ( Q_stristr( token, "[$" ) )
#endif
{ {
if ( !EvaluateConditional( token ) ) if ( !EvaluateConditional( token ) )
{ {

View File

@ -26,9 +26,15 @@ $Group "game"
"responserules" "responserules"
} }
$Group "shaderdlls"
{
"game_shader_dx9"
}
$Group "shaders" $Group "shaders"
{ {
"game_shader_dx9" "game_shader_dx9"
"mathlib"
} }
$Group "everything" $Group "everything"

View File

@ -19,7 +19,7 @@
// Mapbase functionality conditionals // Mapbase functionality conditionals
$Conditional MAPBASE "1" // Equivalent to (and required for) our MAPBASE preprocessor defined below $Conditional MAPBASE "1" // Equivalent to (and required for) our MAPBASE preprocessor defined below
$Conditional MAPBASE_RPC "1" // Toggles Mapbase's Rich Presence Client implementations $Conditional MAPBASE_RPC "0" // Toggles Mapbase's Rich Presence Client implementations (requires discord-rpc.dll in game bin)
$Conditional MAPBASE_VSCRIPT "1" // Toggles VScript implementation (note: interfaces still exist, just the provided implementation is not present) $Conditional MAPBASE_VSCRIPT "1" // Toggles VScript implementation (note: interfaces still exist, just the provided implementation is not present)
$Conditional NEW_RESPONSE_SYSTEM "1" // Toggles the new Response System library based on the Alien Swarm SDK $Conditional NEW_RESPONSE_SYSTEM "1" // Toggles the new Response System library based on the Alien Swarm SDK

View File

@ -141,9 +141,6 @@ $Project
$Implib "$LIBPUBLIC\tier0" $Implib "$LIBPUBLIC\tier0"
$Lib "$LIBPUBLIC\tier1" $Lib "$LIBPUBLIC\tier1"
$Implib "$LIBPUBLIC\vstdlib" $Implib "$LIBPUBLIC\vstdlib"
// Discord integration
$Lib "$LIBPUBLIC\discord-rpc" [$MAPBASE_RPC]
} }
} }

View File

@ -67,8 +67,9 @@ $Configuration
$PostBuildEvent [!$ANALYZE] $PostBuildEvent [!$ANALYZE]
{ {
$CommandLine "if not exist $QUOTE$OUTBINDIR$QUOTE mkdir $QUOTE$OUTBINDIR$QUOTE" "\n" [($VS2015||$VS2017||$VS2019||$VS2022)]
$CommandLine "$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK && ($VS2015||$VS2017||$VS2019||$VS2022)]
$CommandLine "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK && !($VS2015||$VS2017||$VS2019||$VS2022)] $CommandLine "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK && !($VS2015||$VS2017||$VS2019||$VS2022)]
$CommandLine "if not exist $QUOTE$OUTBINDIR$QUOTE mkdir $QUOTE$OUTBINDIR$QUOTE" "\n" [!$SOURCESDK && ($VS2015||$VS2017||$VS2019||$VS2022)]
$CommandLine "$BASE" "copy $QUOTE$(TargetDir)$QUOTE$(TargetFileName) $OUTBINDIR\$(TargetFileName) >nul" "\n" \ $CommandLine "$BASE" "copy $QUOTE$(TargetDir)$QUOTE$(TargetFileName) $OUTBINDIR\$(TargetFileName) >nul" "\n" \
"if ERRORLEVEL 1 goto BuildEventFailed" "\n" \ "if ERRORLEVEL 1 goto BuildEventFailed" "\n" \
"if exist $QUOTE$(TargetDir)$QUOTE$(TargetName).map copy $QUOTE$(TargetDir)$QUOTE$(TargetName).map $OUTBINDIR\$(TargetName).map >nul" "\n" "if exist $QUOTE$(TargetDir)$QUOTE$(TargetName).map copy $QUOTE$(TargetDir)$QUOTE$(TargetName).map $OUTBINDIR\$(TargetName).map >nul" "\n"

View File

@ -539,11 +539,12 @@ void RegisterBaseBindings( IScriptVM *pVM )
ScriptRegisterConstant( pVM, FCVAR_SPONLY, "If this convar flag is set, it can't be changed by clients connected to a multiplayer server." ); ScriptRegisterConstant( pVM, FCVAR_SPONLY, "If this convar flag is set, it can't be changed by clients connected to a multiplayer server." );
ScriptRegisterConstant( pVM, FCVAR_ARCHIVE, "If this convar flag is set, its value will be saved when the game is exited." ); ScriptRegisterConstant( pVM, FCVAR_ARCHIVE, "If this convar flag is set, its value will be saved when the game is exited." );
ScriptRegisterConstant( pVM, FCVAR_NOTIFY, "If this convar flag is set, it will notify players when it is changed." ); ScriptRegisterConstant( pVM, FCVAR_NOTIFY, "If this convar flag is set, it will notify players when it is changed." );
ScriptRegisterConstant( pVM, FCVAR_CHEAT, "Only useable in singleplayer / debug / multiplayer & sv_cheats" );
ScriptRegisterConstant( pVM, FCVAR_USERINFO, "If this convar flag is set, it will be marked as info which plays a part in how the server identifies a client." ); ScriptRegisterConstant( pVM, FCVAR_USERINFO, "If this convar flag is set, it will be marked as info which plays a part in how the server identifies a client." );
ScriptRegisterConstant( pVM, FCVAR_PRINTABLEONLY, "If this convar flag is set, it cannot contain unprintable characters. Used for player name cvars, etc." ); ScriptRegisterConstant( pVM, FCVAR_PRINTABLEONLY, "If this convar flag is set, it cannot contain unprintable characters. Used for player name cvars, etc." );
ScriptRegisterConstant( pVM, FCVAR_UNLOGGED, "If this convar flag is set, it will not log its changes if a log is being created." ); ScriptRegisterConstant( pVM, FCVAR_UNLOGGED, "If this convar flag is set, it will not log its changes if a log is being created." );
ScriptRegisterConstant( pVM, FCVAR_NEVER_AS_STRING, "If this convar flag is set, it will never be printed as a string." ); ScriptRegisterConstant( pVM, FCVAR_NEVER_AS_STRING, "If this convar flag is set, it will never be printed as a string." );
ScriptRegisterConstant( pVM, FCVAR_REPLICATED, "If this convar flag is set, it will enforce a serverside value on any clientside counterparts. (also known as FCAR_SERVER)" ); ScriptRegisterConstant( pVM, FCVAR_REPLICATED, "If this convar flag is set, it will enforce a serverside value on any clientside counterparts. (also known as FCVAR_SERVER)" );
ScriptRegisterConstant( pVM, FCVAR_DEMO, "If this convar flag is set, it will be recorded when starting a demo file." ); ScriptRegisterConstant( pVM, FCVAR_DEMO, "If this convar flag is set, it will be recorded when starting a demo file." );
ScriptRegisterConstant( pVM, FCVAR_DONTRECORD, "If this convar flag is set, it will NOT be recorded when starting a demo file." ); ScriptRegisterConstant( pVM, FCVAR_DONTRECORD, "If this convar flag is set, it will NOT be recorded when starting a demo file." );
ScriptRegisterConstant( pVM, FCVAR_RELOAD_MATERIALS, "If this convar flag is set, it will force a material reload when it changes." ); ScriptRegisterConstant( pVM, FCVAR_RELOAD_MATERIALS, "If this convar flag is set, it will force a material reload when it changes." );

View File

@ -2779,7 +2779,6 @@ bool SquirrelVM::GenerateUniqueKey(const char* pszRoot, char* pBuf, int nBufSize
static int keyIdx = 0; static int keyIdx = 0;
// This gets used for script scope, still confused why it needs to be inside IScriptVM // This gets used for script scope, still confused why it needs to be inside IScriptVM
// is it just to be a compatible name for CreateScope? // is it just to be a compatible name for CreateScope?
SquirrelSafeCheck safeCheck(vm_);
V_snprintf(pBuf, nBufSize, "%08X_%s", ++keyIdx, pszRoot); V_snprintf(pBuf, nBufSize, "%08X_%s", ++keyIdx, pszRoot);
return true; return true;
} }
@ -2971,6 +2970,14 @@ int SquirrelVM::GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey
bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue) bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue)
{ {
#ifdef _DEBUG
AssertMsg( pszKey, "FATAL: cannot get NULL" );
// Don't crash on debug
if ( !pszKey )
return GetValue( hScope, ScriptVariant_t(0), pValue );
#endif
SquirrelSafeCheck safeCheck(vm_); SquirrelSafeCheck safeCheck(vm_);
Assert(pValue); Assert(pValue);