mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 15:11:46 +00:00
- Sync scripting branch with what was in trunk on Sunday. I believe that would be revision 2739.
SVN r2790 (scripting)
This commit is contained in:
commit
99670b708c
317 changed files with 17655 additions and 7629 deletions
|
@ -64,42 +64,39 @@ set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" )
|
|||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX AND PROFILE )
|
||||
set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg" )
|
||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -pg" )
|
||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg" )
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX AND PROFILE )
|
||||
|
||||
if( ZLIB_FOUND )
|
||||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||
|
||||
if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||
message( STATUS "Using system zlib" )
|
||||
else( ZLIB_FOUND )
|
||||
else( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||
message( STATUS "Using internal zlib" )
|
||||
add_subdirectory( zlib )
|
||||
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib )
|
||||
set( ZLIB_LIBRARIES z )
|
||||
set( ZLIB_LIBRARY z )
|
||||
endif( ZLIB_FOUND )
|
||||
endif( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||
|
||||
if( JPEG_FOUND )
|
||||
if( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG )
|
||||
message( STATUS "Using system jpeg library" )
|
||||
else( JPEG_FOUND )
|
||||
else( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG )
|
||||
message( STATUS "Using internal jpeg library" )
|
||||
add_subdirectory( jpeg-6b )
|
||||
set( JPEG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jpeg-6b )
|
||||
set( JPEG_LIBRARIES jpeg )
|
||||
set( JPEG_LIBRARY jpeg )
|
||||
endif( JPEG_FOUND )
|
||||
endif( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG )
|
||||
|
||||
if( BZIP2_FOUND )
|
||||
if( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||
message( STATUS "Using system bzip2 library" )
|
||||
else( BZIP2_FOUND )
|
||||
else( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||
message( STATUS "Using internal bzip2 library" )
|
||||
add_subdirectory( bzip2 )
|
||||
set( BZIP2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/bzip2" )
|
||||
set( BZIP2_LIBRARIES bz2 )
|
||||
set( BZIP2_LIBRARY bz2 )
|
||||
endif( BZIP2_FOUND)
|
||||
endif( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||
|
||||
set( LZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lzma/C" )
|
||||
|
||||
|
|
23
FindFluidSynth.cmake
Normal file
23
FindFluidSynth.cmake
Normal file
|
@ -0,0 +1,23 @@
|
|||
# - Find fluidsynth
|
||||
# Find the native fluidsynth includes and library
|
||||
#
|
||||
# FLUIDSYNTH_INCLUDE_DIR - where to find fluidsynth.h
|
||||
# FLUIDSYNTH_LIBRARIES - List of libraries when using fluidsynth.
|
||||
# FLUIDSYNTH_FOUND - True if fluidsynth found.
|
||||
|
||||
|
||||
IF (FLUIDSYNTH_INCLUDE_DIR AND FLUIDSYNTH_LIBRARIES)
|
||||
# Already in cache, be silent
|
||||
SET(FluidSynth_FIND_QUIETLY TRUE)
|
||||
ENDIF (FLUIDSYNTH_INCLUDE_DIR AND FLUIDSYNTH_LIBRARIES)
|
||||
|
||||
FIND_PATH(FLUIDSYNTH_INCLUDE_DIR fluidsynth.h)
|
||||
|
||||
FIND_LIBRARY(FLUIDSYNTH_LIBRARIES NAMES fluidsynth )
|
||||
MARK_AS_ADVANCED( FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR )
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set FLUIDSYNTH_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FluidSynth DEFAULT_MSG FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR)
|
||||
|
|
@ -1 +1,3 @@
|
|||
This version of ZDoom must be compiled with any version between 4.22 and 4.28 inclusive.
|
||||
Use of the latest 4.26 is recommended though due to technical issues with 4.28.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
===============================================================================
|
||||
Universal Doom Map Format ZDoom extensions v1.8 - 16.07.2009
|
||||
Universal Doom Map Format ZDoom extensions v1.10 - 25.04.2010
|
||||
|
||||
|
||||
Copyright (c) 2008 Christoph Oelckers.
|
||||
|
@ -38,7 +38,8 @@ between the TEXTMAP and ENDMAP lumps:
|
|||
|
||||
BEHAVIOR = contains compiled ACS code
|
||||
DIALOGUE = contains compiled Strife conversation scripts.
|
||||
ZNODES = Nodes (must be stored as compressed GL nodes)
|
||||
ZNODES = Nodes (must be stored as extended GL nodes. Compression is allowed
|
||||
but deprecated for portability reasons.)
|
||||
BLOCKMAP = blockmap. It is recommended not to include this lump in UDMF maps.
|
||||
REJECT = reject table. Recommended use is for special effects only.
|
||||
|
||||
|
@ -88,6 +89,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
alpha = <float>; // Translucency of this line, default is 1.0
|
||||
renderstyle = <string>; // Render style, can be "translucent" or "add",
|
||||
// default is "translucent".
|
||||
playeruseback = <bool>; // New SPAC flag, true = player can use from back side.
|
||||
anycross = <bool>; // New SPAC flag, true = any non-projectile
|
||||
// crossing will trigger this line
|
||||
monsteractivate = <bool>; // Monsters can trigger this line.
|
||||
|
@ -159,6 +161,9 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
nofallingdamage = <bool>; // Falling damage is disabled in this sector
|
||||
dropactors = <bool>; // Actors drop with instantly moving floors (*)
|
||||
norespawn = <bool>; // Players can not respawn in this sector
|
||||
soundsequence = <string>; // The sound sequence to play when this sector moves. Placing a
|
||||
// sound sequence thing in the sector will override this property.
|
||||
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
||||
|
||||
* Note about dropactors
|
||||
|
||||
|
@ -176,6 +181,8 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
class# = <bool> // Unlike the base spec, # can range from 1-8.
|
||||
// 8 is the maximum amount of classes the class
|
||||
// menu can display.
|
||||
conversation = <int> // Assigns a conversation dialogue to this thing.
|
||||
// Parameter is the conversation ID, 0 meaning none.
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,6 +262,21 @@ Added sidedef scaling properties and side specific clipmidtex and wrapmidtex.
|
|||
Added NoDecals sidedef option
|
||||
Fixed conversion specifications for TranslucentLine special.
|
||||
|
||||
1.9 17.04.2010
|
||||
Changed node specifications to deprecate compression of node lump.
|
||||
|
||||
1.10 25.04.2010
|
||||
Added 'playeruseback' line trigger flag.
|
||||
|
||||
1.11 07.08.2010
|
||||
Added 'soundsequnce' sector property.
|
||||
|
||||
1.12 22.08.2010
|
||||
Added 'conversation' thing property.
|
||||
|
||||
1.13 29.08.2010
|
||||
Added 'hidden' sector property.
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
||||
|
|
158
specs/usdf.txt
Normal file
158
specs/usdf.txt
Normal file
|
@ -0,0 +1,158 @@
|
|||
===============================================================================
|
||||
Universal Strife Dialog Format Specification v2.0 - 08/20/10
|
||||
|
||||
Written by Braden "Blzut3" Obrzut - admin@maniacsvault.net
|
||||
|
||||
Defined with input from:
|
||||
|
||||
CodeImp
|
||||
Gez
|
||||
Graf Zahl
|
||||
Quasar
|
||||
et al.
|
||||
|
||||
Copyright (c) 2010 Braden Obrzut.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
===============================================================================
|
||||
|
||||
=======================================
|
||||
I. Grammar / Syntax
|
||||
=======================================
|
||||
|
||||
The grammar and syntax is similar to that of UDMF. A compliant UDMF parser
|
||||
should be applyable to the USDF. However, it will need to be capable of
|
||||
handling sub-blocks. Unknown sub-blocks should be skipped.
|
||||
|
||||
=======================================
|
||||
II. Implementation Semantics
|
||||
=======================================
|
||||
|
||||
------------------------------------
|
||||
II.A : Storage and Retrieval of Data
|
||||
------------------------------------
|
||||
|
||||
This is the same as in UDMF.
|
||||
|
||||
-----------------------------------
|
||||
II.B : Storage Within Archive Files
|
||||
-----------------------------------
|
||||
|
||||
There are two options for the USDF lump placement. This can either be a part
|
||||
of the UDMF lump list or standalone. If used stand alone the lump name
|
||||
DIALOGXY is used corresponding with MAPXY. For UDMF the lump shall be called
|
||||
"DIALOGUE".
|
||||
|
||||
--------------------------------
|
||||
II.C : Implementation Dependence
|
||||
--------------------------------
|
||||
|
||||
USDF also implements the namespace statement. This has all the same
|
||||
requirements as UDMF.
|
||||
|
||||
=======================================
|
||||
III. Standardized Fields
|
||||
=======================================
|
||||
|
||||
The following are required for all USDF complient implementations. Like UDMF,
|
||||
any unknown field/function should be ignored and not treated as an error.
|
||||
|
||||
NOTE: "mobj" refers to Strife's conversationIDs and not doom editor numbers or
|
||||
Hexen's spawnids. A valid mobj value is any positive integer greater
|
||||
than or equal to 1.
|
||||
|
||||
---------------------
|
||||
III.A : Conversations
|
||||
---------------------
|
||||
|
||||
Conversations are groups of pages that can be assigned to a particular object.
|
||||
Implementors should preserve the IDs to allow for dynamic reassignment through
|
||||
scripting although this is not a requirement.
|
||||
|
||||
conversation // Starts a dialog.
|
||||
{
|
||||
actor = <integer>; // mobj for this conversation's actor. If previously
|
||||
// used, this will override the previous conversation.
|
||||
|
||||
page // Starts a new page. Pages are automatically numbered starting at 0.
|
||||
{
|
||||
name = <string>; // Name that goes in the upper left hand corner
|
||||
panel = <string>; // Name of lump to render as the background.
|
||||
voice = <string>; // Narration sound lump.
|
||||
dialog = <string>; // Dialog of the page.
|
||||
drop = <integer>; // mobj for the object to drop if the actor is
|
||||
// killed.
|
||||
link = <integer>; // Page to jump to if all ifitem conditions are
|
||||
// satisified.
|
||||
|
||||
// jumps to the specified page if the player has the specified amount
|
||||
// or more of item in their inventory. This can be repeated as many
|
||||
// times as the author wants, all conditions must be met for the
|
||||
// jump to occur.
|
||||
ifitem
|
||||
{
|
||||
item = <integer>; // mobj of item to check.
|
||||
amount = <integer>; // amount required to be in inventory.
|
||||
}
|
||||
|
||||
// Choices shall be automatically numbered.
|
||||
choice
|
||||
{
|
||||
text = <string>; // Name of the choice.
|
||||
|
||||
// The amount of an item needed to successfully pick this option.
|
||||
// This can be repeated, but only the first will be shown (provided
|
||||
// diaplaycost is true). All costs must be satisfied for success.
|
||||
cost
|
||||
{
|
||||
item = <integer>; // Item that is required for this option.
|
||||
amount = <integer>; // Minimum amount of the item needed.
|
||||
}
|
||||
|
||||
displaycost = <bool>; // Weather the cost should be
|
||||
// displayed with the option.
|
||||
// If no cost is specified this should
|
||||
// be ignored.
|
||||
yesmessage = <string>; // Text to add to console when choice
|
||||
// is accepted.
|
||||
nomessage = <string>; // Text to add to console when choice
|
||||
// is denied.
|
||||
|
||||
log = <string>; // LOG entry to use on success.
|
||||
giveitem = <integer>; // Gives the specified item upon
|
||||
// success.
|
||||
// The following are the same as the special for linedefs in UDMF.
|
||||
// They are executed on success.
|
||||
special = <integer>;
|
||||
arg0 = <integer>;
|
||||
arg1 = <integer>;
|
||||
arg2 = <integer>;
|
||||
arg3 = <integer>;
|
||||
arg4 = <integer>;
|
||||
|
||||
nextpage = <integer>; // Sets the next page.
|
||||
closedialog = <bool>; // Should the dialog be closed upon
|
||||
// selecting this choice?
|
||||
// Default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-------------------------------
|
||||
III.B : Including Other Dialogs
|
||||
-------------------------------
|
||||
|
||||
Unlike the original Strife dialog format. The lump "SCRIPT00" should not be
|
||||
included automatically. Instead the user must specify this behavior by using
|
||||
the include function, which takes the name of a lump to include. Include only
|
||||
needs to be available in the global scope and for compatibility reasons, must
|
||||
include the result of the script and not act like a preprocessor statement.
|
||||
|
||||
include = <string>;
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
89
specs/usdf_zdoom.txt
Normal file
89
specs/usdf_zdoom.txt
Normal file
|
@ -0,0 +1,89 @@
|
|||
===============================================================================
|
||||
ZDoom Strife Dialog Format ZDoom v1.1 - 23.08.2010
|
||||
based on Universal Strife Dialog Format v2.0
|
||||
|
||||
Copyright (c) 2010 Christoph Oelckers.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
===============================================================================
|
||||
|
||||
=======================================
|
||||
I. Grammar / Syntax
|
||||
=======================================
|
||||
|
||||
No changes.
|
||||
|
||||
=======================================
|
||||
II. Implementation Semantics
|
||||
=======================================
|
||||
|
||||
No changes.
|
||||
|
||||
=======================================
|
||||
III. Changes to USDF spec
|
||||
=======================================
|
||||
|
||||
ZDoom Strife Dialogue format implements the USDF base specification as described with one important change:
|
||||
To take advantage of named actor classes any field specifying an actor type
|
||||
by a conversationID takes a class name instead.
|
||||
The following fields are affected by this change:
|
||||
|
||||
conversation
|
||||
{
|
||||
actor = <string>;
|
||||
|
||||
page
|
||||
{
|
||||
drop = <string>;
|
||||
ifitem
|
||||
{
|
||||
item = <string>;
|
||||
}
|
||||
|
||||
choice
|
||||
{
|
||||
cost
|
||||
{
|
||||
item = <string>;
|
||||
}
|
||||
|
||||
giveitem = <string>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
It should be noted that this change creates an incompatibility with USDF
|
||||
so technically speaking the ZDoom format is no longer 'real' USDF.
|
||||
To accomodate what is needed here this is unavoidable, unfortunately.
|
||||
Any proper USDF implementation not supporting named actor classes should
|
||||
either refuse loading dialogues with the 'ZDoom' namespace or if it does not
|
||||
outright abort on incompatible namespaces fail with a type mismatch error on
|
||||
one of the specified propeties.
|
||||
|
||||
ZDoom-format dialogues need to start with the line:
|
||||
|
||||
namespace = "ZDoom";
|
||||
|
||||
|
||||
---------------------
|
||||
III.A : Conversations
|
||||
---------------------
|
||||
|
||||
This block only lists the newly added fields. Currently ZDoom only adds one
|
||||
field to the specification:
|
||||
|
||||
conversation // Starts a dialog.
|
||||
{
|
||||
id = <int>; // assigns an ID to a dialogue. IDs are used to dynamically assign
|
||||
// dialogues to actors. For 'Strife' namespace or binary dialogues
|
||||
// the standard conversation ID ('actor' property) is used instead
|
||||
// for this purpose but since 'ZDoom' namespace requires the actor
|
||||
// to be a class name it needs a separate field for this.
|
||||
}
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
|
@ -6,13 +6,21 @@ endif( COMMAND cmake_policy )
|
|||
|
||||
include( CheckCXXSourceCompiles )
|
||||
include( CheckFunctionExists )
|
||||
include( CheckCXXCompilerFlag )
|
||||
include( FindPkgConfig )
|
||||
|
||||
option( NO_ASM "Disable assembly code" )
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
option( NO_STRIP "Do not strip Release or MinSizeRel builds" )
|
||||
# At least some versions of Xcode fail if you strip with the linker
|
||||
# instead of the separate strip utility.
|
||||
if( APPLE )
|
||||
set( NO_STRIP ON )
|
||||
endif( APPLE )
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
||||
option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" )
|
||||
|
||||
if( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||
set( X64 64 )
|
||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||
|
@ -25,6 +33,10 @@ endif( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
|||
# fmodapi<version>linux[64] -or simply- fmod
|
||||
# jpeg-6b
|
||||
# ...
|
||||
# The recommended method is to put it in the zdoom tree, since its
|
||||
# headers are unversioned. Especially now that we can't work properly
|
||||
# with anything newer than 4.26.xx, you probably don't want to use
|
||||
# a system-wide version.
|
||||
|
||||
# Construct version numbers for searching for the FMOD library on Linux.
|
||||
set( MINOR_VERSIONS "50" "49" "48" "47" "46" "45" "44" "43" "42" "41"
|
||||
|
@ -32,7 +44,7 @@ set( MINOR_VERSIONS "50" "49" "48" "47" "46" "45" "44" "43" "42" "41"
|
|||
"27" "26" "25" "24" "23" "22" "21" "20" "21" "19" "18" "17" "16"
|
||||
"15" "14" "13" "12" "11" "10" "09" "08" "07" "06" "05" "04" "03"
|
||||
"02" "01" "00" )
|
||||
set( MAJOR_VERSIONS "26" "24" "22" "20" )
|
||||
set( MAJOR_VERSIONS "30" "28" "26" "24" "22" "20" )
|
||||
set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "../fmod" )
|
||||
foreach( majver ${MAJOR_VERSIONS} )
|
||||
foreach( minver ${MINOR_VERSIONS} )
|
||||
|
@ -230,14 +242,11 @@ else( FMOD_LIBRARY )
|
|||
endif( FMOD_LIBRARY )
|
||||
|
||||
|
||||
# Search for NASM
|
||||
# Search for FluidSynth
|
||||
|
||||
if( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc )
|
||||
if( NOT NO_ASM )
|
||||
message( STATUS "Disabling assembly code for PowerPC." )
|
||||
set( NO_ASM ON )
|
||||
endif( NOT NO_ASM )
|
||||
endif( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc )
|
||||
include( ../FindFluidSynth.cmake )
|
||||
|
||||
# Search for NASM
|
||||
|
||||
if( NOT NO_ASM )
|
||||
if( UNIX AND X64 )
|
||||
|
@ -297,7 +306,12 @@ if( NOT NO_ASM )
|
|||
set( ASM_FLAGS )
|
||||
set( ASM_SOURCE_EXTENSION .s )
|
||||
else( X64 )
|
||||
set( ASM_FLAGS -f elf -DM_TARGET_LINUX -i${CMAKE_CURRENT_SOURCE_DIR}/ )
|
||||
if( APPLE )
|
||||
set( ASM_FLAGS -fmacho -DM_TARGET_MACHO )
|
||||
else( APPLE )
|
||||
set( ASM_FLAGS -felf -DM_TARGET_LINUX )
|
||||
endif( APPLE )
|
||||
set( ASM_FLAGS "${ASM_FLAGS}" -i${CMAKE_CURRENT_SOURCE_DIR}/ )
|
||||
set( ASM_SOURCE_EXTENSION .asm )
|
||||
endif( X64 )
|
||||
else( UNIX )
|
||||
|
@ -327,9 +341,52 @@ if( NOT NO_ASM )
|
|||
ENDMACRO( ADD_ASM_FILE )
|
||||
endif( NOT NO_ASM )
|
||||
|
||||
# Decide on SSE setup
|
||||
|
||||
set( SSE_MATTERS NO )
|
||||
|
||||
# SSE only matters on 32-bit targets. We check compiler flags to know if we can do it.
|
||||
if( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||
CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH )
|
||||
CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 )
|
||||
if( CAN_DO_MFPMATH )
|
||||
set( SSE1_ENABLE "-msse -mfpmath=sse" )
|
||||
set( SSE2_ENABLE "-msse2 -mfpmath=sse" )
|
||||
set( SSE_MATTERS YES )
|
||||
elseif( CAN_DO_ARCHSSE2 )
|
||||
set( SSE1_ENABLE -arch:SSE )
|
||||
set( SSE2_ENABLE -arch:SSE2 )
|
||||
set( SSE_MATTERS YES )
|
||||
endif( CAN_DO_MFPMATH )
|
||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||
|
||||
if( SSE_MATTERS )
|
||||
if( WIN32 )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else( WIN32 )
|
||||
CHECK_FUNCTION_EXISTS(mprotect HAVE_MPROTECT)
|
||||
if( HAVE_MPROTECT )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else( HAVE_MPROTECT )
|
||||
set( BACKPATCH 0 )
|
||||
endif( HAVE_MPROTECT )
|
||||
endif( WIN32 )
|
||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||
else( SSE_MATTERS )
|
||||
set( BACKPATCH 0 )
|
||||
endif( SSE_MATTERS )
|
||||
|
||||
# Set up flags for GCC
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
if( PROFILE )
|
||||
set( CMAKE_C_FLinclude( FindFluidSynth.cmake )
|
||||
AGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg" )
|
||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -pg" )
|
||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg" )
|
||||
endif( PROFILE )
|
||||
|
||||
set( REL_CXX_FLAGS "-fno-rtti" )
|
||||
if( NOT PROFILE )
|
||||
set( REL_CXX_FLAGS "${REL_CXX_FLAGS} -fomit-frame-pointer" )
|
||||
|
@ -375,6 +432,13 @@ if( NOT STRNICMP_EXISTS )
|
|||
add_definitions( -Dstrnicmp=strncasecmp )
|
||||
endif( NOT STRNICMP_EXISTS )
|
||||
|
||||
if( NOT WIN32 )
|
||||
CHECK_FUNCTION_EXISTS( sigtimedwait SIGTIMEDWAIT_EXISTS )
|
||||
if( SIGTIMEDWAIT_EXISTS )
|
||||
add_definitions( -DHAVE_SIGTIMEDWAIT )
|
||||
endif( SIGTIMEDWAIT_EXISTS )
|
||||
endif( NOT WIN32)
|
||||
|
||||
if( NOT MSVC )
|
||||
add_definitions( -D__forceinline=inline )
|
||||
endif( NOT MSVC )
|
||||
|
@ -408,6 +472,12 @@ if( NOT HAS_VA_COPY )
|
|||
endif( HAS___VA_COPY )
|
||||
endif( NOT HAS_VA_COPY )
|
||||
|
||||
# Flags
|
||||
|
||||
if( BACKPATCH )
|
||||
add_definitions( -DBACKPATCH )
|
||||
endif( BACKPATCH )
|
||||
|
||||
# Update svnrevision.h
|
||||
|
||||
add_custom_target( revision_check ALL
|
||||
|
@ -417,8 +487,16 @@ add_custom_target( revision_check ALL
|
|||
|
||||
# Libraries ZDoom needs
|
||||
|
||||
message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${FMOD_LIBRARY}" )
|
||||
include_directories( "${ZLIB_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" )
|
||||
include_directories( "${ZLIB_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" )
|
||||
|
||||
if( FLUIDSYNTH_FOUND )
|
||||
if( NOT DYN_FLUIDSYNTH)
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FLUIDSYNTH_LIBRARIES}" )
|
||||
include_directories( "${FLUIDSYNTH_INCLUDE_DIR}" )
|
||||
endif( NOT DYN_FLUIDSYNTH )
|
||||
endif( FLUIDSYNTH_FOUND )
|
||||
|
||||
# Start defining source files for ZDoom
|
||||
|
||||
|
@ -466,7 +544,7 @@ else( WIN32 )
|
|||
sdl/sdlvideo.cpp
|
||||
sdl/st_start.cpp )
|
||||
if( APPLE )
|
||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} sdl/SDLMain.m )
|
||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} sdl/SDLMain.m sdl/iwadpicker_cocoa.mm )
|
||||
endif( APPLE )
|
||||
endif( WIN32 )
|
||||
|
||||
|
@ -507,12 +585,23 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h
|
|||
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
if( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc )
|
||||
if( SSE_MATTERS )
|
||||
if( SSE )
|
||||
set( X86_SOURCES nodebuild_classify_sse2.cpp )
|
||||
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "${SSE2_ENABLE}" )
|
||||
else( SSE )
|
||||
add_definitions( -DDISABLE_SSE )
|
||||
endif( SSE )
|
||||
else( SSE_MATTERS )
|
||||
add_definitions( -DDISABLE_SSE )
|
||||
set( X86_SOURCES )
|
||||
set( NOT_X86 ON )
|
||||
else( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc )
|
||||
set( X86_SOURCES nodebuild_classify_sse2.cpp )
|
||||
endif( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc )
|
||||
endif( SSE_MATTERS )
|
||||
|
||||
if( DYN_FLUIDSYNTH )
|
||||
add_definitions( -DHAVE_FLUIDSYNTH -DDYN_FLUIDSYNTH )
|
||||
elseif( FLUIDSYNTH_FOUND )
|
||||
add_definitions( -DHAVE_FLUIDSYNTH )
|
||||
endif( DYN_FLUIDSYNTH )
|
||||
|
||||
add_executable( zdoom WIN32
|
||||
autostart.cpp
|
||||
|
@ -578,7 +667,6 @@ add_executable( zdoom WIN32
|
|||
m_png.cpp
|
||||
m_random.cpp
|
||||
md5.cpp
|
||||
mus2midi.cpp
|
||||
name.cpp
|
||||
nodebuild.cpp
|
||||
nodebuild_classify_nosse2.cpp
|
||||
|
@ -596,6 +684,7 @@ add_executable( zdoom WIN32
|
|||
p_effect.cpp
|
||||
p_enemy.cpp
|
||||
p_floor.cpp
|
||||
p_glnodes.cpp
|
||||
p_interaction.cpp
|
||||
p_lights.cpp
|
||||
p_linkedsectors.cpp
|
||||
|
@ -620,6 +709,7 @@ add_executable( zdoom WIN32
|
|||
p_tick.cpp
|
||||
p_trace.cpp
|
||||
p_udmf.cpp
|
||||
p_usdf.cpp
|
||||
p_user.cpp
|
||||
p_writemap.cpp
|
||||
p_xlat.cpp
|
||||
|
@ -663,9 +753,7 @@ add_executable( zdoom WIN32
|
|||
zstring.cpp
|
||||
g_doom/a_doommisc.cpp
|
||||
g_heretic/a_hereticmisc.cpp
|
||||
g_heretic/heretic_sbar.cpp
|
||||
g_hexen/a_hexenmisc.cpp
|
||||
g_hexen/hexen_sbar.cpp
|
||||
g_raven/a_artitele.cpp
|
||||
g_raven/a_minotaur.cpp
|
||||
g_strife/a_strifestuff.cpp
|
||||
|
@ -729,13 +817,16 @@ add_executable( zdoom WIN32
|
|||
sound/music_cd.cpp
|
||||
sound/music_dumb.cpp
|
||||
sound/music_gme.cpp
|
||||
sound/music_mus_midiout.cpp
|
||||
sound/music_smf_midiout.cpp
|
||||
sound/music_hmi_midiout.cpp
|
||||
sound/music_midistream.cpp
|
||||
sound/music_midi_base.cpp
|
||||
sound/music_midi_midiout.cpp
|
||||
sound/music_midi_timidity.cpp
|
||||
sound/music_mus_midiout.cpp
|
||||
sound/music_mus_opl.cpp
|
||||
sound/music_stream.cpp
|
||||
sound/music_fluidsynth_mididevice.cpp
|
||||
sound/music_softsynth_mididevice.cpp
|
||||
sound/music_timidity_mididevice.cpp
|
||||
sound/music_win_mididevice.cpp
|
||||
textures/automaptexture.cpp
|
||||
|
@ -824,21 +915,12 @@ if( NOT WIN32 )
|
|||
COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/link-make
|
||||
COMMAND /bin/sh -c ${CMAKE_CURRENT_BINARY_DIR}/link-make )
|
||||
endif( NOT WIN32 )
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
# GCC misoptimizes this file
|
||||
set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" )
|
||||
|
||||
# Compile this one file with SSE2 support.
|
||||
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mfpmath=sse" )
|
||||
|
||||
# Need to enable intrinsics for this file.
|
||||
if( NOT NOT_X86 )
|
||||
if( SSE_MATTERS )
|
||||
set_source_files_properties( x86.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" )
|
||||
endif( NOT NOT_X86 )
|
||||
endif( SSE_MATTERS )
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
||||
if( MSVC )
|
||||
# Compile this one file with SSE2 support.
|
||||
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "/arch:SSE2" )
|
||||
endif( MSVC )
|
||||
|
|
|
@ -56,7 +56,8 @@ DEFINE_SPECIAL(Sector_ChangeFlags, 54, 3, 3, 3)
|
|||
DEFINE_SPECIAL(Line_SetBlocking, 55, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Line_SetTextureScale, 56, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Sector_SetPortal, 57, -1, -1, 5)
|
||||
|
||||
DEFINE_SPECIAL(Sector_CopyScroller, 58, -1, -1, 2)
|
||||
DEFINE_SPECIAL(Polyobj_OR_MoveToSpot, 59, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Plat_PerpetualRaise, 60, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Plat_Stop, 61, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Plat_DownWaitUpStay, 62, 3, 3, 3)
|
||||
|
@ -76,14 +77,17 @@ DEFINE_SPECIAL(Teleport_EndGame, 75, 0, 0, 0)
|
|||
DEFINE_SPECIAL(TeleportOther, 76, 3, 3, 3)
|
||||
DEFINE_SPECIAL(TeleportGroup, 77, 5, 5, 5)
|
||||
DEFINE_SPECIAL(TeleportInSector, 78, 4, 5, 5)
|
||||
|
||||
DEFINE_SPECIAL(Thing_SetConversation, 79, 2, 2, 2)
|
||||
DEFINE_SPECIAL(ACS_Execute, 80, 1, 5, 5)
|
||||
DEFINE_SPECIAL(ACS_Suspend, 81, 2, 2, 2)
|
||||
DEFINE_SPECIAL(ACS_Terminate, 82, 2, 2, 2)
|
||||
DEFINE_SPECIAL(ACS_LockedExecute, 83, 5, 5, 5)
|
||||
DEFINE_SPECIAL(ACS_ExecuteWithResult, 84, 1, 4, 4)
|
||||
DEFINE_SPECIAL(ACS_LockedExecuteDoor, 85, 5, 5, 5)
|
||||
|
||||
DEFINE_SPECIAL(Polyobj_MoveToSpot, 86, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Polyobj_Stop, 87, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Polyobj_MoveTo, 88, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Polyobj_OR_MoveTo, 89, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Polyobj_OR_RotateLeft, 90, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Polyobj_OR_RotateRight, 91, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Polyobj_OR_Move, 92, 4, 4, 4)
|
||||
|
@ -110,7 +114,9 @@ DEFINE_SPECIAL(Plane_Copy, 118, -1, -1, 5)
|
|||
DEFINE_SPECIAL(Thing_Damage, 119, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Radius_Quake, 120, 5, 5, 5) // Earthquake
|
||||
DEFINE_SPECIAL(Line_SetIdentification, 121, -1, -1, 5)
|
||||
|
||||
DEFINE_SPECIAL(Thing_Move, 125, 2, 3, 3)
|
||||
|
||||
DEFINE_SPECIAL(Thing_SetSpecial, 127, 5, 5, 5)
|
||||
DEFINE_SPECIAL(ThrustThingZ, 128, 4, 4, 4)
|
||||
DEFINE_SPECIAL(UsePuzzleItem, 129, 2, 5, 5)
|
||||
|
|
39
src/actor.h
39
src/actor.h
|
@ -40,6 +40,7 @@
|
|||
#include "r_blend.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
struct subsector_t;
|
||||
class PClassAmmo;
|
||||
|
||||
//
|
||||
|
@ -262,7 +263,7 @@ enum
|
|||
MF4_NOEXTREMEDEATH = 0x10000000, // this projectile or weapon never gibs its victim
|
||||
MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim
|
||||
MF4_FRIGHTENED = 0x40000000, // Monster runs away from player
|
||||
/* = 0x80000000, */
|
||||
MF4_BOSSSPAWNED = 0x80000000, // Spawned by a boss spawn cube
|
||||
|
||||
// --- mobj.flags5 ---
|
||||
|
||||
|
@ -321,6 +322,9 @@ enum
|
|||
MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions
|
||||
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
|
||||
MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse)
|
||||
MF6_BLOCKEDBYSOLIDACTORS = 0x00080000, // Blocked by solid actors, even if not solid itself
|
||||
MF6_ADDITIVEPOISONDAMAGE = 0x00100000,
|
||||
MF6_ADDITIVEPOISONDURATION = 0x00200000,
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
@ -616,7 +620,7 @@ public:
|
|||
bool CheckLocalView (int playernum) const;
|
||||
|
||||
// Finds the first item of a particular type.
|
||||
AInventory *FindInventory (PClassActor *type);
|
||||
AInventory *FindInventory (PClassActor *type, bool subclass=false);
|
||||
AInventory *FindInventory (FName type);
|
||||
template<class T> T *FindInventory ()
|
||||
{
|
||||
|
@ -695,22 +699,29 @@ public:
|
|||
|
||||
PClassActor *GetBloodType(int type = 0) const
|
||||
{
|
||||
PClassActor *bloodcls;
|
||||
if (type == 0)
|
||||
{
|
||||
return PClass::FindActor(GetClass()->BloodType);
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType);
|
||||
}
|
||||
else if (type == 1)
|
||||
{
|
||||
return PClass::FindActor(GetClass()->BloodType2);
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType2);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
return PClass::FindActor(GetClass()->BloodType3);
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bloodcls != NULL)
|
||||
{
|
||||
bloodcls = bloodcls->GetReplacement();
|
||||
}
|
||||
return bloodcls;
|
||||
}
|
||||
|
||||
// Calculate amount of missile damage
|
||||
|
@ -742,6 +753,7 @@ public:
|
|||
fixed_t pitch, roll;
|
||||
FBlockNode *BlockNode; // links in blocks (if needed)
|
||||
struct sector_t *Sector;
|
||||
subsector_t * subsector;
|
||||
fixed_t floorz, ceilingz; // closest together of contacted secs
|
||||
fixed_t dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.
|
||||
|
||||
|
@ -820,6 +832,15 @@ public:
|
|||
AActor *BlockingMobj; // Actor that blocked the last move
|
||||
line_t *BlockingLine; // Line that blocked the last move
|
||||
|
||||
int PoisonDamage; // Damage received per tic from poison.
|
||||
int PoisonDuration; // Duration left for receiving poison damage.
|
||||
int PoisonPeriod; // How often poison damage is applied. (Every X tics.)
|
||||
|
||||
int PoisonDamageReceived; // Damage received per tic from poison.
|
||||
int PoisonDurationReceived; // Duration left for receiving poison damage.
|
||||
int PoisonPeriodReceived; // How often poison damage is applied. (Every X tics.)
|
||||
TObjPtr<AActor> Poisoner; // Last source of received poison damage.
|
||||
|
||||
// a linked list of sectors where this object appears
|
||||
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
||||
|
||||
|
@ -859,8 +880,9 @@ public:
|
|||
FState *MeleeState;
|
||||
FState *MissileState;
|
||||
|
||||
// [RH] The dialogue to show when this actor is "used."
|
||||
FStrifeDialogueNode *Conversation;
|
||||
|
||||
int ConversationRoot; // THe root of the current dialogue
|
||||
FStrifeDialogueNode *Conversation; // [RH] The dialogue to show when this actor is "used."
|
||||
|
||||
// [RH] Decal(s) this weapon/projectile generates on impact.
|
||||
FDecalBase *DecalGenerator;
|
||||
|
@ -890,8 +912,7 @@ public:
|
|||
void SetOrigin (fixed_t x, fixed_t y, fixed_t z);
|
||||
bool InStateSequence(FState * newstate, FState * basestate);
|
||||
int GetTics(FState * newstate);
|
||||
bool SetState (FState *newstate);
|
||||
bool SetStateNF (FState *newstate);
|
||||
bool SetState (FState *newstate, bool nofunction=false);
|
||||
virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true);
|
||||
bool isFast();
|
||||
void SetIdle();
|
||||
|
|
659
src/am_map.cpp
659
src/am_map.cpp
|
@ -36,6 +36,9 @@
|
|||
#include "r_translate.h"
|
||||
#include "d_event.h"
|
||||
#include "gi.h"
|
||||
#include "r_bsp.h"
|
||||
#include "p_setup.h"
|
||||
#include "c_bind.h"
|
||||
|
||||
#include "m_cheat.h"
|
||||
#include "i_system.h"
|
||||
|
@ -58,6 +61,8 @@
|
|||
|
||||
#include "am_map.h"
|
||||
#include "a_artifacts.h"
|
||||
#include "po_man.h"
|
||||
#include "a_keys.h"
|
||||
|
||||
struct AMColor
|
||||
{
|
||||
|
@ -79,7 +84,7 @@ struct AMColor
|
|||
|
||||
static AMColor Background, YourColor, WallColor, TSWallColor,
|
||||
FDWallColor, CDWallColor, ThingColor,
|
||||
ThingColor_Item, ThingColor_Monster, ThingColor_Friend,
|
||||
ThingColor_Item, ThingColor_CountItem, ThingColor_Monster, ThingColor_Friend,
|
||||
SecretWallColor, GridColor, XHairColor,
|
||||
NotSeenColor,
|
||||
LockedColor,
|
||||
|
@ -170,27 +175,66 @@ CVAR (Color, am_secretsectorcolor, 0xff00ff, CVAR_ARCHIVE);
|
|||
CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_drawmapback, true, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_thingcolor_item, 0xfcfcfc, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_thingcolor_citem, 0xfcfcfc, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_ovthingcolor_friend, 0xe88800, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_ovthingcolor_monster, 0xe88800, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE);
|
||||
CVAR (Color, am_ovthingcolor_citem, 0xe88800, CVAR_ARCHIVE);
|
||||
|
||||
|
||||
static int bigstate = 0;
|
||||
static bool textured = 1; // internal toggle for texture mode
|
||||
|
||||
CUSTOM_CVAR(Bool, am_textured, false, CVAR_ARCHIVE)
|
||||
{
|
||||
textured |= self;
|
||||
}
|
||||
|
||||
CVAR(Int, am_showsubsector, -1, 0);
|
||||
|
||||
|
||||
// Disable the ML_DONTDRAW line flag if x% of all lines in a map are flagged with it
|
||||
// (To counter annoying mappers who think they are smart by making the automap unusable)
|
||||
bool am_showallenabled;
|
||||
|
||||
CUSTOM_CVAR (Int, am_showalllines, -1, 0) // This is a cheat so don't save it.
|
||||
{
|
||||
int flagged = 0;
|
||||
int total = 0;
|
||||
if (self > 0 && numlines > 0)
|
||||
{
|
||||
for(int i=0;i<numlines;i++)
|
||||
{
|
||||
line_t *line = &lines[i];
|
||||
|
||||
// disregard intra-sector lines
|
||||
if (line->frontsector == line->backsector) continue;
|
||||
|
||||
// disregard control sectors for deep water
|
||||
if (line->frontsector->e->FakeFloor.Sectors.Size() > 0) continue;
|
||||
|
||||
// disregard control sectors for 3D-floors
|
||||
if (line->frontsector->e->XFloor.attached.Size() > 0) continue;
|
||||
|
||||
total++;
|
||||
if (line->flags & ML_DONTDRAW) flagged++;
|
||||
}
|
||||
am_showallenabled = (flagged * 100 / total >= self);
|
||||
}
|
||||
else if (self == 0)
|
||||
{
|
||||
am_showallenabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
am_showallenabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// drawing stuff
|
||||
#define AM_PANDOWNKEY KEY_DOWNARROW
|
||||
#define AM_PANUPKEY KEY_UPARROW
|
||||
#define AM_PANRIGHTKEY KEY_RIGHTARROW
|
||||
#define AM_PANLEFTKEY KEY_LEFTARROW
|
||||
#define AM_ZOOMINKEY KEY_EQUALS
|
||||
#define AM_ZOOMINKEY2 0x4e // DIK_ADD
|
||||
#define AM_ZOOMOUTKEY KEY_MINUS
|
||||
#define AM_ZOOMOUTKEY2 0x4a // DIK_SUBTRACT
|
||||
#define AM_GOBIGKEY 0x0b // DIK_0
|
||||
#define AM_FOLLOWKEY 'f'
|
||||
#define AM_GRIDKEY 'g'
|
||||
#define AM_MARKKEY 'm'
|
||||
#define AM_CLEARMARKKEY 'c'
|
||||
|
||||
#define AM_NUMMARKPOINTS 10
|
||||
|
||||
|
@ -202,10 +246,10 @@ CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE);
|
|||
#define F_PANINC (140/TICRATE)
|
||||
// how much zoom-in per tic
|
||||
// goes to 2x in 1 second
|
||||
#define M_ZOOMIN ((int) (1.02*MAPUNIT))
|
||||
#define M_ZOOMIN (1.02*MAPUNIT)
|
||||
// how much zoom-out per tic
|
||||
// pulls out to 0.5x in 1 second
|
||||
#define M_ZOOMOUT ((int) (MAPUNIT/1.02))
|
||||
#define M_ZOOMOUT (MAPUNIT/1.02)
|
||||
|
||||
// translates between frame-buffer and map coordinates
|
||||
#define CXMTOF(x) (MTOF((x)-m_x)/* - f_x*/)
|
||||
|
@ -253,25 +297,22 @@ mline_t player_arrow[] = {
|
|||
{ { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
|
||||
{ { -R+3*R/8, 0 }, { -R+R/8, -R/4 } }
|
||||
};
|
||||
#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
|
||||
|
||||
mline_t player_arrow_raven[] = {
|
||||
{ { -R+R/4, 0 }, { 0, 0} }, // center line.
|
||||
{ { -R+R/4, R/8 }, { R, 0} }, // blade
|
||||
{ { -R+R/4, -R/8 }, { R, 0 } },
|
||||
{ { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece
|
||||
{ { -R+R/8, -R/4 }, { -R+R/8, R/4 } },
|
||||
{ { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors
|
||||
{ { -R+R/8, R/4 }, { -R+R/4, R/4} },
|
||||
{ { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel
|
||||
{ { -R-R/4, R/8 }, { -R+R/8, R/8 } },
|
||||
{ { -R-R/4, -R/8}, { -R+R/8, -R/8 } }
|
||||
};
|
||||
|
||||
#undef R
|
||||
#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
|
||||
{ { -R+R/4, 0 }, { 0, 0} }, // center line.
|
||||
{ { -R+R/4, R/8 }, { R, 0} }, // blade
|
||||
{ { -R+R/4, -R/8 }, { R, 0 } },
|
||||
{ { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece
|
||||
{ { -R+R/8, -R/4 }, { -R+R/8, R/4 } },
|
||||
{ { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors
|
||||
{ { -R+R/8, R/4 }, { -R+R/4, R/4} },
|
||||
{ { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel
|
||||
{ { -R-R/4, R/8 }, { -R+R/8, R/8 } },
|
||||
{ { -R-R/4, -R/8}, { -R+R/8, -R/8 } }
|
||||
};
|
||||
#define NUMPLYRLINES_RAVEN (sizeof(player_arrow_raven)/sizeof(mline_t))
|
||||
|
||||
#define R ((8*PLAYERRADIUS)/7)
|
||||
mline_t cheat_player_arrow[] = {
|
||||
{ { -R+R/8, 0 }, { R, 0 } }, // -----
|
||||
{ { R, 0 }, { R-R/2, R/6 } }, // ----->
|
||||
|
@ -290,9 +331,9 @@ mline_t cheat_player_arrow[] = {
|
|||
{ { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } },
|
||||
{ { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } }
|
||||
};
|
||||
#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
|
||||
|
||||
#undef R
|
||||
#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
|
||||
|
||||
#define R (MAPUNIT)
|
||||
// [RH] Avoid lots of warnings without compiler-specific #pragmas
|
||||
|
@ -309,9 +350,37 @@ mline_t thintriangle_guy[] = {
|
|||
L (1,0, -.5,.7),
|
||||
L (-.5,.7, -.5,-.7)
|
||||
};
|
||||
#define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
|
||||
|
||||
mline_t square_guy[] = {
|
||||
L (0,1,1,0),
|
||||
L (1,0,0,-1),
|
||||
L (0,-1,-1,0),
|
||||
L (-1,0,0,1)
|
||||
};
|
||||
#define NUMSQUAREGUYLINES (sizeof(square_guy)/sizeof(mline_t))
|
||||
|
||||
#undef R
|
||||
#define R (MAPUNIT)
|
||||
|
||||
mline_t key_guy[] = {
|
||||
L (-2, 0, -1.7, -0.5),
|
||||
L (-1.7, -0.5, -1.5, -0.7),
|
||||
L (-1.5, -0.7, -0.8, -0.5),
|
||||
L (-0.8, -0.5, -0.6, 0),
|
||||
L (-0.6, 0, -0.8, 0.5),
|
||||
L (-1.5, 0.7, -0.8, 0.5),
|
||||
L (-1.7, 0.5, -1.5, 0.7),
|
||||
L (-2, 0, -1.7, 0.5),
|
||||
L (-0.6, 0, 2, 0),
|
||||
L (1.7, 0, 1.7, -1),
|
||||
L (1.5, 0, 1.5, -1),
|
||||
L (1.3, 0, 1.3, -1)
|
||||
};
|
||||
#define NUMKEYGUYLINES (sizeof(key_guy)/sizeof(mline_t))
|
||||
|
||||
#undef L
|
||||
#undef R
|
||||
#define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
|
||||
|
||||
|
||||
|
||||
|
@ -344,7 +413,7 @@ static int amclock;
|
|||
|
||||
static mpoint_t m_paninc; // how far the window pans each tic (map coords)
|
||||
static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords)
|
||||
static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
|
||||
static float am_zoomdir;
|
||||
|
||||
static fixed_t m_x, m_y; // LL x,y where the window is on the map (map coords)
|
||||
static fixed_t m_x2, m_y2; // UR x,y where the window is on the map (map coords)
|
||||
|
@ -393,7 +462,69 @@ static void AM_calcMinMaxMtoF();
|
|||
void AM_rotatePoint (fixed_t *x, fixed_t *y);
|
||||
void AM_rotate (fixed_t *x, fixed_t *y, angle_t an);
|
||||
void AM_doFollowPlayer ();
|
||||
static void AM_ToggleFollowPlayer();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// map functions
|
||||
//
|
||||
//=============================================================================
|
||||
bool AM_addMark ();
|
||||
bool AM_clearMarks ();
|
||||
void AM_saveScaleAndLoc ();
|
||||
void AM_restoreScaleAndLoc ();
|
||||
void AM_minOutWindowScale ();
|
||||
|
||||
|
||||
CCMD(am_togglefollow)
|
||||
{
|
||||
followplayer = !followplayer;
|
||||
f_oldloc.x = FIXED_MAX;
|
||||
Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF"));
|
||||
}
|
||||
|
||||
CCMD(am_togglegrid)
|
||||
{
|
||||
grid = !grid;
|
||||
Printf ("%s\n", GStrings(grid ? "AMSTR_GRIDON" : "AMSTR_GRIDOFF"));
|
||||
}
|
||||
|
||||
CCMD(am_toggletexture)
|
||||
{
|
||||
if (am_textured && hasglnodes)
|
||||
{
|
||||
textured = !textured;
|
||||
Printf ("%s\n", GStrings(textured ? "AMSTR_TEXON" : "AMSTR_TEXOFF"));
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(am_setmark)
|
||||
{
|
||||
if (AM_addMark())
|
||||
{
|
||||
Printf ("%s %d\n", GStrings("AMSTR_MARKEDSPOT"), markpointnum);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(am_clearmarks)
|
||||
{
|
||||
if (AM_clearMarks())
|
||||
{
|
||||
Printf ("%s\n", GStrings("AMSTR_MARKSCLEARED"));
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(am_gobig)
|
||||
{
|
||||
bigstate = !bigstate;
|
||||
if (bigstate)
|
||||
{
|
||||
AM_saveScaleAndLoc();
|
||||
AM_minOutWindowScale();
|
||||
}
|
||||
else
|
||||
AM_restoreScaleAndLoc();
|
||||
}
|
||||
|
||||
// Calculates the slope and slope according to the x-axis of a line
|
||||
// segment in map coordinates (with the upright y-axis n' all) so
|
||||
|
@ -702,11 +833,19 @@ void AM_initVariables ()
|
|||
|
||||
automapactive = true;
|
||||
|
||||
// Reset AM buttons
|
||||
Button_AM_PanLeft.Reset();
|
||||
Button_AM_PanRight.Reset();
|
||||
Button_AM_PanUp.Reset();
|
||||
Button_AM_PanDown.Reset();
|
||||
Button_AM_ZoomIn.Reset();
|
||||
Button_AM_ZoomOut.Reset();
|
||||
|
||||
|
||||
f_oldloc.x = FIXED_MAX;
|
||||
amclock = 0;
|
||||
|
||||
m_paninc.x = m_paninc.y = 0;
|
||||
ftom_zoommul = MAPUNIT;
|
||||
mtof_zoommul = MAPUNIT;
|
||||
|
||||
m_w = FTOM(SCREENWIDTH);
|
||||
|
@ -774,6 +913,7 @@ static void AM_initColors (bool overlayed)
|
|||
SecretWallColor = WallColor;
|
||||
SecretSectorColor.FromCVar (am_ovsecretsectorcolor);
|
||||
ThingColor_Item.FromCVar (am_ovthingcolor_item);
|
||||
ThingColor_CountItem.FromCVar (am_ovthingcolor_citem);
|
||||
ThingColor_Friend.FromCVar (am_ovthingcolor_friend);
|
||||
ThingColor_Monster.FromCVar (am_ovthingcolor_monster);
|
||||
ThingColor.FromCVar (am_ovthingcolor);
|
||||
|
@ -797,6 +937,7 @@ static void AM_initColors (bool overlayed)
|
|||
FDWallColor.FromCVar (am_fdwallcolor);
|
||||
CDWallColor.FromCVar (am_cdwallcolor);
|
||||
ThingColor_Item.FromCVar (am_thingcolor_item);
|
||||
ThingColor_CountItem.FromCVar (am_thingcolor_citem);
|
||||
ThingColor_Friend.FromCVar (am_thingcolor_friend);
|
||||
ThingColor_Monster.FromCVar (am_thingcolor_monster);
|
||||
ThingColor.FromCVar (am_thingcolor);
|
||||
|
@ -946,6 +1087,8 @@ void AM_LevelInit ()
|
|||
if (scale_mtof > max_scale_mtof)
|
||||
scale_mtof = min_scale_mtof;
|
||||
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
|
||||
|
||||
am_showalllines.Callback();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1081,127 +1224,28 @@ void AM_ToggleMap ()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
bool AM_Responder (event_t *ev)
|
||||
bool AM_Responder (event_t *ev, bool last)
|
||||
{
|
||||
bool rc;
|
||||
static int cheatstate = 0;
|
||||
static int bigstate = 0;
|
||||
|
||||
rc = false;
|
||||
|
||||
if (automapactive && ev->type == EV_KeyDown)
|
||||
if (automapactive && (ev->type == EV_KeyDown || ev->type == EV_KeyUp))
|
||||
{
|
||||
rc = true;
|
||||
switch (ev->data1)
|
||||
if (followplayer)
|
||||
{
|
||||
case AM_PANRIGHTKEY: // pan right
|
||||
if (!followplayer)
|
||||
m_paninc.x = FTOM(F_PANINC);
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANLEFTKEY: // pan left
|
||||
if (!followplayer)
|
||||
m_paninc.x = -FTOM(F_PANINC);
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANUPKEY: // pan up
|
||||
if (!followplayer)
|
||||
m_paninc.y = FTOM(F_PANINC);
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANDOWNKEY: // pan down
|
||||
if (!followplayer)
|
||||
m_paninc.y = -FTOM(F_PANINC);
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_ZOOMOUTKEY: // zoom out
|
||||
case AM_ZOOMOUTKEY2:
|
||||
mtof_zoommul = M_ZOOMOUT;
|
||||
ftom_zoommul = M_ZOOMIN;
|
||||
break;
|
||||
case AM_ZOOMINKEY: // zoom in
|
||||
case AM_ZOOMINKEY2:
|
||||
mtof_zoommul = M_ZOOMIN;
|
||||
ftom_zoommul = M_ZOOMOUT;
|
||||
break;
|
||||
case AM_GOBIGKEY:
|
||||
bigstate = !bigstate;
|
||||
if (bigstate)
|
||||
{
|
||||
AM_saveScaleAndLoc();
|
||||
AM_minOutWindowScale();
|
||||
}
|
||||
else
|
||||
AM_restoreScaleAndLoc();
|
||||
break;
|
||||
default:
|
||||
switch (ev->data2)
|
||||
{
|
||||
case AM_FOLLOWKEY:
|
||||
AM_ToggleFollowPlayer();
|
||||
break;
|
||||
case AM_GRIDKEY:
|
||||
grid = !grid;
|
||||
Printf ("%s\n", GStrings(grid ? "AMSTR_GRIDON" : "AMSTR_GRIDOFF"));
|
||||
break;
|
||||
case AM_MARKKEY:
|
||||
if (AM_addMark())
|
||||
{
|
||||
Printf ("%s %d\n", GStrings("AMSTR_MARKEDSPOT"), markpointnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = false;
|
||||
}
|
||||
break;
|
||||
case AM_CLEARMARKKEY:
|
||||
if (AM_clearMarks())
|
||||
{
|
||||
Printf ("%s\n", GStrings("AMSTR_MARKSCLEARED"));
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cheatstate = 0;
|
||||
rc = false;
|
||||
}
|
||||
// check for am_pan* and ignore in follow mode
|
||||
const char *defbind = AutomapBindings.GetBind(ev->data1);
|
||||
if (!strnicmp(defbind, "+am_pan", 7)) return false;
|
||||
}
|
||||
}
|
||||
else if (ev->type == EV_KeyUp)
|
||||
{
|
||||
rc = false;
|
||||
switch (ev->data1)
|
||||
{
|
||||
case AM_PANRIGHTKEY:
|
||||
if (!followplayer) m_paninc.x = 0;
|
||||
break;
|
||||
case AM_PANLEFTKEY:
|
||||
if (!followplayer) m_paninc.x = 0;
|
||||
break;
|
||||
case AM_PANUPKEY:
|
||||
if (!followplayer) m_paninc.y = 0;
|
||||
break;
|
||||
case AM_PANDOWNKEY:
|
||||
if (!followplayer) m_paninc.y = 0;
|
||||
break;
|
||||
case AM_ZOOMOUTKEY:
|
||||
case AM_ZOOMOUTKEY2:
|
||||
case AM_ZOOMINKEY:
|
||||
case AM_ZOOMINKEY2:
|
||||
mtof_zoommul = MAPUNIT;
|
||||
ftom_zoommul = MAPUNIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
bool res = C_DoKey(ev, &AutomapBindings, NULL);
|
||||
if (res && ev->type == EV_KeyUp && !last)
|
||||
{
|
||||
// If this is a release event we also need to check if it released a button in the main Bindings
|
||||
// so that that button does not get stuck.
|
||||
const char *defbind = Bindings.GetBind(ev->data1);
|
||||
return (defbind[0] != '+'); // Let G_Responder handle button releases
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1213,6 +1257,26 @@ bool AM_Responder (event_t *ev)
|
|||
|
||||
void AM_changeWindowScale ()
|
||||
{
|
||||
int mtof_zoommul;
|
||||
|
||||
if (am_zoomdir > 0)
|
||||
{
|
||||
mtof_zoommul = int(M_ZOOMIN * am_zoomdir);
|
||||
}
|
||||
else if (am_zoomdir < 0)
|
||||
{
|
||||
mtof_zoommul = int(M_ZOOMOUT / -am_zoomdir);
|
||||
}
|
||||
else if (Button_AM_ZoomIn.bDown)
|
||||
{
|
||||
mtof_zoommul = int(M_ZOOMIN);
|
||||
}
|
||||
else if (Button_AM_ZoomOut.bDown)
|
||||
{
|
||||
mtof_zoommul = int(M_ZOOMOUT);
|
||||
}
|
||||
am_zoomdir = 0;
|
||||
|
||||
// Change the scaling multipliers
|
||||
scale_mtof = MapMul(scale_mtof, mtof_zoommul);
|
||||
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
|
||||
|
@ -1223,6 +1287,13 @@ void AM_changeWindowScale ()
|
|||
AM_maxOutWindowScale();
|
||||
}
|
||||
|
||||
CCMD(am_zoom)
|
||||
{
|
||||
if (argv.argc() >= 2)
|
||||
{
|
||||
am_zoomdir = (float)atof(argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
@ -1257,19 +1328,6 @@ void AM_doFollowPlayer ()
|
|||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static void AM_ToggleFollowPlayer()
|
||||
{
|
||||
followplayer = !followplayer;
|
||||
f_oldloc.x = FIXED_MAX;
|
||||
Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF"));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Updates on Game Tick
|
||||
|
@ -1284,10 +1342,20 @@ void AM_Ticker ()
|
|||
amclock++;
|
||||
|
||||
if (followplayer)
|
||||
{
|
||||
AM_doFollowPlayer();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_paninc.x = m_paninc.y = 0;
|
||||
if (Button_AM_PanLeft.bDown) m_paninc.x -= FTOM(F_PANINC);
|
||||
if (Button_AM_PanRight.bDown) m_paninc.x += FTOM(F_PANINC);
|
||||
if (Button_AM_PanUp.bDown) m_paninc.y += FTOM(F_PANINC);
|
||||
if (Button_AM_PanDown.bDown) m_paninc.y -= FTOM(F_PANINC);
|
||||
}
|
||||
|
||||
// Change the zoom if necessary
|
||||
if (ftom_zoommul != MAPUNIT)
|
||||
if (Button_AM_ZoomIn.bDown || Button_AM_ZoomOut.bDown || am_zoomdir != 0)
|
||||
AM_changeWindowScale();
|
||||
|
||||
// Change x,y location
|
||||
|
@ -1545,6 +1613,97 @@ void AM_drawGrid (const AMColor &color)
|
|||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// AM_drawSubsectors
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_drawSubsectors()
|
||||
{
|
||||
static TArray<FVector2> points;
|
||||
float scale = float(scale_mtof);
|
||||
angle_t rotation;
|
||||
sector_t tempsec;
|
||||
int floorlight, ceilinglight;
|
||||
double originx, originy;
|
||||
FDynamicColormap *colormap;
|
||||
|
||||
|
||||
for (int i = 0; i < numsubsectors; ++i)
|
||||
{
|
||||
if (subsectors[i].flags & SSECF_POLYORG)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((!(subsectors[i].flags & SSECF_DRAWN) || (subsectors[i].render_sector->MoreFlags & SECF_HIDDEN)) && am_cheat == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Fill the points array from the subsector.
|
||||
points.Resize(subsectors[i].numlines);
|
||||
for (DWORD j = 0; j < subsectors[i].numlines; ++j)
|
||||
{
|
||||
mpoint_t pt = { subsectors[i].firstline[j].v1->x >> FRACTOMAPBITS,
|
||||
subsectors[i].firstline[j].v1->y >> FRACTOMAPBITS };
|
||||
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
|
||||
{
|
||||
AM_rotatePoint(&pt.x, &pt.y);
|
||||
}
|
||||
points[j].X = f_x + ((pt.x - m_x) * scale / float(1 << 24));
|
||||
points[j].Y = f_y + (f_h - (pt.y - m_y) * scale / float(1 << 24));
|
||||
}
|
||||
// For lighting and texture determination
|
||||
sector_t *sec = R_FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight,
|
||||
&ceilinglight, false);
|
||||
// Find texture origin.
|
||||
mpoint_t originpt = { -sec->GetXOffset(sector_t::floor) >> FRACTOMAPBITS,
|
||||
sec->GetYOffset(sector_t::floor) >> FRACTOMAPBITS };
|
||||
rotation = 0 - sec->GetAngle(sector_t::floor);
|
||||
// Apply the floor's rotation to the texture origin.
|
||||
if (rotation != 0)
|
||||
{
|
||||
AM_rotate(&originpt.x, &originpt.y, rotation);
|
||||
}
|
||||
// Apply the automap's rotation to the texture origin.
|
||||
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
|
||||
{
|
||||
rotation += ANG90 - players[consoleplayer].camera->angle;
|
||||
AM_rotatePoint(&originpt.x, &originpt.y);
|
||||
}
|
||||
originx = f_x + ((originpt.x - m_x) * scale / float(1 << 24));
|
||||
originy = f_y + (f_h - (originpt.y - m_y) * scale / float(1 << 24));
|
||||
// Coloring for the polygon
|
||||
colormap = sec->ColorMap;
|
||||
// If this subsector has not actually been seen yet (because you are cheating
|
||||
// to see it on the map), tint and desaturate it.
|
||||
if (!(subsectors[i].flags & SSECF_DRAWN))
|
||||
{
|
||||
colormap = GetSpecialLights(
|
||||
MAKERGB(
|
||||
(colormap->Color.r + 255) / 2,
|
||||
(colormap->Color.g + 200) / 2,
|
||||
(colormap->Color.b + 160) / 2),
|
||||
colormap->Fade,
|
||||
255 - (255 - colormap->Desaturate) / 4);
|
||||
floorlight = (floorlight + 200*15) / 16;
|
||||
}
|
||||
|
||||
// Draw the polygon.
|
||||
screen->FillSimplePoly(
|
||||
TexMan(sec->GetTexture(sector_t::floor)),
|
||||
&points[0], points.Size(),
|
||||
originx, originy,
|
||||
scale / (FIXED2FLOAT(sec->GetXScale(sector_t::floor)) * float(1 << MAPBITS)),
|
||||
scale / (FIXED2FLOAT(sec->GetYScale(sector_t::floor)) * float(1 << MAPBITS)),
|
||||
rotation,
|
||||
colormap,
|
||||
floorlight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1573,6 +1732,80 @@ static bool AM_CheckSecret(line_t *line)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Polyobject debug stuff
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_drawSeg(seg_t *seg, const AMColor &color)
|
||||
{
|
||||
mline_t l;
|
||||
l.a.x = seg->v1->x >> FRACTOMAPBITS;
|
||||
l.a.y = seg->v1->y >> FRACTOMAPBITS;
|
||||
l.b.x = seg->v2->x >> FRACTOMAPBITS;
|
||||
l.b.y = seg->v2->y >> FRACTOMAPBITS;
|
||||
|
||||
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
|
||||
{
|
||||
AM_rotatePoint (&l.a.x, &l.a.y);
|
||||
AM_rotatePoint (&l.b.x, &l.b.y);
|
||||
}
|
||||
AM_drawMline(&l, color);
|
||||
}
|
||||
|
||||
void AM_drawPolySeg(FPolySeg *seg, const AMColor &color)
|
||||
{
|
||||
mline_t l;
|
||||
l.a.x = seg->v1.x >> FRACTOMAPBITS;
|
||||
l.a.y = seg->v1.y >> FRACTOMAPBITS;
|
||||
l.b.x = seg->v2.x >> FRACTOMAPBITS;
|
||||
l.b.y = seg->v2.y >> FRACTOMAPBITS;
|
||||
|
||||
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
|
||||
{
|
||||
AM_rotatePoint (&l.a.x, &l.a.y);
|
||||
AM_rotatePoint (&l.b.x, &l.b.y);
|
||||
}
|
||||
AM_drawMline(&l, color);
|
||||
}
|
||||
|
||||
void AM_showSS()
|
||||
{
|
||||
if (am_showsubsector >= 0 && am_showsubsector < numsubsectors)
|
||||
{
|
||||
AMColor yellow;
|
||||
yellow.FromRGB(255,255,0);
|
||||
AMColor red;
|
||||
red.FromRGB(255,0,0);
|
||||
|
||||
subsector_t *sub = &subsectors[am_showsubsector];
|
||||
for (unsigned int i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
AM_drawSeg(sub->firstline + i, yellow);
|
||||
}
|
||||
PO_LinkToSubsectors();
|
||||
|
||||
for (int i = 0; i <po_NumPolyobjs; i++)
|
||||
{
|
||||
FPolyObj *po = &polyobjs[i];
|
||||
FPolyNode *pnode = po->subsectorlinks;
|
||||
|
||||
while (pnode != NULL)
|
||||
{
|
||||
if (pnode->subsector == sub)
|
||||
{
|
||||
for (unsigned j = 0; j < pnode->segs.Size(); j++)
|
||||
{
|
||||
AM_drawPolySeg(&pnode->segs[j], red);
|
||||
}
|
||||
}
|
||||
pnode = pnode->snext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Determines visible lines, draws them.
|
||||
|
@ -1601,7 +1834,12 @@ void AM_drawWalls (bool allmap)
|
|||
if (am_cheat != 0 || (lines[i].flags & ML_MAPPED))
|
||||
{
|
||||
if ((lines[i].flags & ML_DONTDRAW) && am_cheat == 0)
|
||||
continue;
|
||||
{
|
||||
if (!am_showallenabled || CheckCheatmode(false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (AM_CheckSecret(&lines[i]))
|
||||
{
|
||||
|
@ -1680,8 +1918,14 @@ void AM_drawWalls (bool allmap)
|
|||
}
|
||||
else if (allmap)
|
||||
{
|
||||
if (!(lines[i].flags & ML_DONTDRAW))
|
||||
AM_drawMline(&l, NotSeenColor);
|
||||
if ((lines[i].flags & ML_DONTDRAW) && am_cheat == 0)
|
||||
{
|
||||
if (!am_showallenabled || CheckCheatmode(false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
AM_drawMline(&l, NotSeenColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1694,14 +1938,27 @@ void AM_drawWalls (bool allmap)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_rotate (fixed_t *x, fixed_t *y, angle_t a)
|
||||
void AM_rotate(fixed_t *xp, fixed_t *yp, angle_t a)
|
||||
{
|
||||
fixed_t tmpx;
|
||||
static angle_t angle_saved = 0;
|
||||
static double sinrot = 0;
|
||||
static double cosrot = 1;
|
||||
|
||||
a >>= ANGLETOFINESHIFT;
|
||||
tmpx = DMulScale16 (*x,finecosine[a],*y,-finesine[a]);
|
||||
*y = DMulScale16 (*x,finesine[a],*y,finecosine[a]);
|
||||
*x = tmpx;
|
||||
if (angle_saved != a)
|
||||
{
|
||||
angle_saved = a;
|
||||
double rot = (double)a / (double)(1u << 31) * (double)M_PI;
|
||||
sinrot = sin(rot);
|
||||
cosrot = cos(rot);
|
||||
}
|
||||
|
||||
double x = FIXED2FLOAT(*xp);
|
||||
double y = FIXED2FLOAT(*yp);
|
||||
double tmpx = (x * cosrot) - (y * sinrot);
|
||||
y = (x * sinrot) + (y * cosrot);
|
||||
x = tmpx;
|
||||
*xp = FLOAT2FIXED(x);
|
||||
*yp = FLOAT2FIXED(y);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1912,11 +2169,40 @@ void AM_drawThings ()
|
|||
if (t->flags & MF_FRIENDLY || !(t->flags & MF_COUNTKILL)) color = ThingColor_Friend;
|
||||
else color = ThingColor_Monster;
|
||||
}
|
||||
else if (t->flags&MF_SPECIAL) color = ThingColor_Item;
|
||||
else if (t->flags&MF_SPECIAL)
|
||||
{
|
||||
// Find the key's own color.
|
||||
// Only works correctly if single-key locks have lower numbers than any-key locks.
|
||||
// That is the case for all default keys, however.
|
||||
if (t->IsKindOf(RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
if (am_showkeys)
|
||||
{
|
||||
int P_GetMapColorForKey (AInventory * key);
|
||||
int c = P_GetMapColorForKey(static_cast<AKey *>(t));
|
||||
|
||||
AM_drawLineCharacter
|
||||
(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
|
||||
16<<MAPBITS, angle, color, p.x, p.y);
|
||||
if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c));
|
||||
else color = ThingColor_CountItem;
|
||||
AM_drawLineCharacter(key_guy, NUMKEYGUYLINES, 16<<MAPBITS, 0, color, p.x, p.y);
|
||||
color.Index = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = ThingColor_Item;
|
||||
}
|
||||
}
|
||||
else if (t->flags&MF_COUNTITEM)
|
||||
color = ThingColor_CountItem;
|
||||
else
|
||||
color = ThingColor_Item;
|
||||
}
|
||||
|
||||
if (color.Index != -1)
|
||||
{
|
||||
AM_drawLineCharacter
|
||||
(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
|
||||
16<<MAPBITS, angle, color, p.x, p.y);
|
||||
}
|
||||
|
||||
if (am_cheat >= 3)
|
||||
{
|
||||
|
@ -2041,7 +2327,11 @@ void AM_drawAuthorMarkers ()
|
|||
|
||||
while (marked != NULL)
|
||||
{
|
||||
if (mark->args[1] == 0 || (mark->args[1] == 1 && marked->Sector->MoreFlags & SECF_DRAWN))
|
||||
// Use more correct info if we have GL nodes available
|
||||
if (mark->args[1] == 0 ||
|
||||
(mark->args[1] == 1 && (hasglnodes ?
|
||||
marked->subsector->flags & SSECF_DRAWN :
|
||||
marked->Sector->MoreFlags & SECF_DRAWN)))
|
||||
{
|
||||
DrawMarker (tex, marked->x >> FRACTOMAPBITS, marked->y >> FRACTOMAPBITS, 0,
|
||||
flip, mark->scaleX, mark->scaleY, mark->Translation,
|
||||
|
@ -2075,7 +2365,7 @@ void AM_Drawer ()
|
|||
return;
|
||||
|
||||
bool allmap = (level.flags2 & LEVEL2_ALLMAP) != 0;
|
||||
bool allthings = allmap && players[consoleplayer].mo->FindInventory<APowerScanner>() != NULL;
|
||||
bool allthings = allmap && players[consoleplayer].mo->FindInventory(RUNTIME_CLASS(APowerScanner), true) != NULL;
|
||||
|
||||
AM_initColors (viewactive);
|
||||
|
||||
|
@ -2100,6 +2390,9 @@ void AM_Drawer ()
|
|||
}
|
||||
AM_activateNewScale();
|
||||
|
||||
if (am_textured && hasglnodes && textured && !viewactive)
|
||||
AM_drawSubsectors();
|
||||
|
||||
if (grid)
|
||||
AM_drawGrid(GridColor);
|
||||
|
||||
|
@ -2114,6 +2407,8 @@ void AM_Drawer ()
|
|||
AM_drawCrosshair(XHairColor);
|
||||
|
||||
AM_drawMarks();
|
||||
|
||||
AM_showSS();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -26,7 +26,7 @@ struct event_t;
|
|||
class FArchive;
|
||||
|
||||
// Called by main loop.
|
||||
bool AM_Responder (event_t* ev);
|
||||
bool AM_Responder (event_t* ev, bool last);
|
||||
|
||||
// Called by main loop.
|
||||
void AM_Ticker (void);
|
||||
|
|
|
@ -93,7 +93,16 @@ setupvlineasm:
|
|||
selfmod premach3a, machvsh8+6
|
||||
ret
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
SECTION .text align=64
|
||||
%else
|
||||
SECTION .rtext progbits alloc exec write align=64
|
||||
%endif
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_a_start
|
||||
_rtext_a_start:
|
||||
%endif
|
||||
|
||||
;eax = xscale
|
||||
;ebx = palookupoffse
|
||||
|
@ -325,6 +334,7 @@ setupmvlineasm:
|
|||
mov ecx, dword [esp+4]
|
||||
mov byte [maskmach3a+2], cl
|
||||
mov byte [machmv13+2], cl
|
||||
|
||||
mov byte [machmv14+2], cl
|
||||
mov byte [machmv15+2], cl
|
||||
mov byte [machmv16+2], cl
|
||||
|
@ -538,3 +548,8 @@ ALIGN 16
|
|||
mvcase0: jmp beginmvlineasm4
|
||||
|
||||
align 16
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_a_end
|
||||
_rtext_a_end:
|
||||
%endif
|
||||
|
|
|
@ -285,7 +285,16 @@ R_SetSpanSize_ASM:
|
|||
|
||||
aret: ret
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
SECTION .text align=64
|
||||
%else
|
||||
SECTION .rtext progbits alloc exec write align=64
|
||||
%endif
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_tmap_start
|
||||
_rtext_tmap_start:
|
||||
%endif
|
||||
|
||||
rtext_start:
|
||||
|
||||
|
@ -300,6 +309,8 @@ GLOBAL R_DrawSpanP_ASM
|
|||
; edi: dest
|
||||
; ebp: scratch
|
||||
; esi: count
|
||||
; [esp]: xstep
|
||||
; [esp+4]: ystep
|
||||
|
||||
align 16
|
||||
|
||||
|
@ -315,6 +326,7 @@ R_DrawSpanP_ASM:
|
|||
push edi
|
||||
push ebp
|
||||
push esi
|
||||
sub esp, 8
|
||||
|
||||
mov edi,ecx
|
||||
add edi,[dc_destorg]
|
||||
|
@ -326,13 +338,13 @@ dsy1: shl edx,6
|
|||
dsy3: shr ebp,26
|
||||
xor ebx,ebx
|
||||
lea esi,[eax+1]
|
||||
mov [ds_xstep],edx
|
||||
mov [esp],edx
|
||||
mov edx,[ds_ystep]
|
||||
mov ecx,[ds_xfrac]
|
||||
dsy4: shr ecx,26
|
||||
dsm8: and edx,0xffffffc0
|
||||
or ebp,edx
|
||||
mov [ds_ystep],ebp
|
||||
mov [esp+4],ebp
|
||||
mov ebp,[ds_yfrac]
|
||||
mov edx,[ds_xfrac]
|
||||
dsy2: shl edx,6
|
||||
|
@ -346,8 +358,8 @@ dsm9: and ebp,0xffffffc0
|
|||
mov ebp,ecx
|
||||
dsx1: rol ebp,6
|
||||
dsm1: and ebp,0xfff
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
spreada mov bl,[ebp+SPACEFILLER4]
|
||||
spmapa mov bl,[ebx+SPACEFILLER4]
|
||||
mov [edi],bl
|
||||
|
@ -358,13 +370,13 @@ dseven1 shr esi,1
|
|||
|
||||
; do two more pixels
|
||||
mov ebp,ecx
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
dsm2: and ebp,0xfc00003f
|
||||
dsx2: rol ebp,6
|
||||
mov eax,ecx
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
spreadb mov bl,[ebp+SPACEFILLER4] ;read texel1
|
||||
dsx3: rol eax,6
|
||||
dsm6: and eax,0xfff
|
||||
|
@ -383,13 +395,13 @@ dsrest test esi,esi
|
|||
align 16
|
||||
|
||||
dsloop mov ebp,ecx
|
||||
spstep1d add edx,[ds_xstep]
|
||||
spstep2d adc ecx,[ds_ystep]
|
||||
spstep1d add edx,[esp]
|
||||
spstep2d adc ecx,[esp+4]
|
||||
dsm3: and ebp,0xfc00003f
|
||||
dsx4: rol ebp,6
|
||||
mov eax,ecx
|
||||
spstep1e add edx,[ds_xstep]
|
||||
spstep2e adc ecx,[ds_ystep]
|
||||
spstep1e add edx,[esp]
|
||||
spstep2e adc ecx,[esp+4]
|
||||
spreadd mov bl,[ebp+SPACEFILLER4] ;read texel1
|
||||
dsx5: rol eax,6
|
||||
dsm5: and eax,0xfff
|
||||
|
@ -397,8 +409,8 @@ spmapd mov bl,[ebx+SPACEFILLER4] ;map texel1
|
|||
mov [edi],bl ;store texel1
|
||||
mov ebp,ecx
|
||||
spreade mov bl,[eax+SPACEFILLER4] ;read texel2
|
||||
spstep1f add edx,[ds_xstep]
|
||||
spstep2f adc ecx,[ds_ystep]
|
||||
spstep1f add edx,[esp]
|
||||
spstep2f adc ecx,[esp+4]
|
||||
dsm4: and ebp,0xfc00003f
|
||||
dsx6: rol ebp,6
|
||||
spmape mov bl,[ebx+SPACEFILLER4] ;map texel2
|
||||
|
@ -411,14 +423,15 @@ dsx7: rol eax,6
|
|||
dsm7: and eax,0xfff
|
||||
mov [edi-2],bl ;store texel3
|
||||
spreadg mov bl,[eax+SPACEFILLER4] ;read texel4
|
||||
spstep1g add edx,[ds_xstep]
|
||||
spstep2g adc ecx,[ds_ystep]
|
||||
spstep1g add edx,[esp]
|
||||
spstep2g adc ecx,[esp+4]
|
||||
spmapg mov bl,[ebx+SPACEFILLER4] ;map texel4
|
||||
dec esi
|
||||
mov [edi-1],bl ;store texel4
|
||||
jnz near dsloop
|
||||
|
||||
dsdone pop esi
|
||||
dsdone add esp,8
|
||||
pop esi
|
||||
pop ebp
|
||||
pop edi
|
||||
pop ebx
|
||||
|
@ -439,6 +452,8 @@ GLOBAL R_DrawSpanMaskedP_ASM
|
|||
; edi: dest
|
||||
; ebp: scratch
|
||||
; esi: count
|
||||
; [esp]: xstep
|
||||
; [esp+4]: ystep
|
||||
|
||||
align 16
|
||||
|
||||
|
@ -454,6 +469,7 @@ R_DrawSpanMaskedP_ASM:
|
|||
push edi
|
||||
push ebp
|
||||
push esi
|
||||
sub esp,8
|
||||
|
||||
mov edi,ecx
|
||||
add edi,[dc_destorg]
|
||||
|
@ -465,13 +481,13 @@ dmsy1: shl edx,6
|
|||
dmsy3: shr ebp,26
|
||||
xor ebx,ebx
|
||||
lea esi,[eax+1]
|
||||
mov [ds_xstep],edx
|
||||
mov [esp],edx
|
||||
mov edx,[ds_ystep]
|
||||
mov ecx,[ds_xfrac]
|
||||
dmsy4: shr ecx,26
|
||||
dmsm8: and edx,0xffffffc0
|
||||
or ebp,edx
|
||||
mov [ds_ystep],ebp
|
||||
mov [esp+4],ebp
|
||||
mov ebp,[ds_yfrac]
|
||||
mov edx,[ds_xfrac]
|
||||
dmsy2: shl edx,6
|
||||
|
@ -485,8 +501,8 @@ dmsm9: and ebp,0xffffffc0
|
|||
mov ebp,ecx
|
||||
dmsx1: rol ebp,6
|
||||
dmsm1: and ebp,0xfff
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
mspreada mov bl,[ebp+SPACEFILLER4]
|
||||
cmp bl,0
|
||||
je mspskipa
|
||||
|
@ -499,13 +515,13 @@ dmseven1 shr esi,1
|
|||
|
||||
; do two more pixels
|
||||
mov ebp,ecx
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
dmsm2: and ebp,0xfc00003f
|
||||
dmsx2: rol ebp,6
|
||||
mov eax,ecx
|
||||
add edx,[ds_xstep]
|
||||
adc ecx,[ds_ystep]
|
||||
add edx,[esp]
|
||||
adc ecx,[esp+4]
|
||||
mspreadb mov bl,[ebp+SPACEFILLER4] ;read texel1
|
||||
dmsx3: rol eax,6
|
||||
dmsm6: and eax,0xfff
|
||||
|
@ -528,13 +544,13 @@ dmsrest test esi,esi
|
|||
align 16
|
||||
|
||||
dmsloop mov ebp,ecx
|
||||
mspstep1d add edx,[ds_xstep]
|
||||
mspstep2d adc ecx,[ds_ystep]
|
||||
mspstep1d add edx,[esp]
|
||||
mspstep2d adc ecx,[esp+4]
|
||||
dmsm3: and ebp,0xfc00003f
|
||||
dmsx4: rol ebp,6
|
||||
mov eax,ecx
|
||||
mspstep1e add edx,[ds_xstep]
|
||||
mspstep2e adc ecx,[ds_ystep]
|
||||
mspstep1e add edx,[esp]
|
||||
mspstep2e adc ecx,[esp+4]
|
||||
mspreadd mov bl,[ebp+SPACEFILLER4] ;read texel1
|
||||
dmsx5: rol eax,6
|
||||
dmsm5: and eax,0xfff
|
||||
|
@ -544,8 +560,8 @@ dmsm5: and eax,0xfff
|
|||
mspmapd mov bl,[ebx+SPACEFILLER4] ;map texel1
|
||||
mov [edi],bl ;store texel1
|
||||
mspreade mov bl,[eax+SPACEFILLER4] ;read texel2
|
||||
mspstep1f add edx,[ds_xstep]
|
||||
mspstep2f adc ecx,[ds_ystep]
|
||||
mspstep1f add edx,[esp]
|
||||
mspstep2f adc ecx,[esp+4]
|
||||
dmsm4: and ebp,0xfc00003f
|
||||
dmsx6: rol ebp,6
|
||||
cmp bl,0
|
||||
|
@ -562,8 +578,8 @@ dmsm7: and eax,0xfff
|
|||
mspmapf mov bl,[ebx+SPACEFILLER4] ;map texel3
|
||||
mov [edi-2],bl ;store texel3
|
||||
mspreadg mov bl,[eax+SPACEFILLER4] ;read texel4
|
||||
mspstep1g add edx,[ds_xstep]
|
||||
mspstep2g adc ecx,[ds_ystep]
|
||||
mspstep1g add edx,[esp]
|
||||
mspstep2g adc ecx,[esp+4]
|
||||
cmp bl,0
|
||||
je mspskipg
|
||||
mspmapg mov bl,[ebx+SPACEFILLER4] ;map texel4
|
||||
|
@ -571,7 +587,8 @@ mspmapg mov bl,[ebx+SPACEFILLER4] ;map texel4
|
|||
mspskipg dec esi
|
||||
jnz near dmsloop
|
||||
|
||||
dmsdone pop esi
|
||||
dmsdone add esp,8
|
||||
pop esi
|
||||
pop ebp
|
||||
pop edi
|
||||
pop ebx
|
||||
|
@ -1738,6 +1755,10 @@ ac4nil: pop edi
|
|||
ret
|
||||
|
||||
rtext_end:
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_tmap_end
|
||||
_rtext_tmap_end:
|
||||
%endif
|
||||
align 16
|
||||
|
||||
;************************
|
||||
|
|
|
@ -216,7 +216,13 @@ SetTiltedSpanSize:
|
|||
|
||||
ret
|
||||
|
||||
%ifndef M_TARGET_MACHO
|
||||
SECTION .rtext progbits alloc exec write align=64
|
||||
%else
|
||||
SECTION .text align=64
|
||||
GLOBAL _rtext_tmap2_start
|
||||
_rtext_tmap2_start:
|
||||
%endif
|
||||
|
||||
rtext_start:
|
||||
|
||||
|
@ -628,3 +634,7 @@ fetch10 mov al,[ebp+esi+SPACEFILLER4]
|
|||
ret
|
||||
|
||||
rtext_end:
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_tmap2_end
|
||||
_rtext_tmap2_end:
|
||||
%endif
|
||||
|
|
|
@ -80,7 +80,13 @@ setupvlinetallasm:
|
|||
selfmod shifter1, shift12+6
|
||||
ret
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
SECTION .text align=64
|
||||
GLOBAL _rtext_tmap3_start
|
||||
_rtext_tmap3_start:
|
||||
%else
|
||||
SECTION .rtext progbits alloc exec write align=64
|
||||
%endif
|
||||
|
||||
ALIGN 16
|
||||
|
||||
|
@ -331,3 +337,8 @@ shift12: shr ecx,16
|
|||
pop ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
%ifdef M_TARGET_MACHO
|
||||
GLOBAL _rtext_tmap3_end
|
||||
_rtext_tmap3_end:
|
||||
%endif
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
#%include "valgrind.inc"
|
||||
#%include "valgrind.inc"
|
||||
|
||||
.section .text
|
||||
.section .text
|
||||
|
||||
.globl ASM_PatchPitch
|
||||
ASM_PatchPitch:
|
||||
.globl ASM_PatchPitch
|
||||
ASM_PatchPitch:
|
||||
movl dc_pitch(%rip), %ecx
|
||||
movl %ecx, pm+3(%rip)
|
||||
movl %ecx, vltpitch+3(%rip)
|
||||
# selfmod pm, vltpitch+6
|
||||
ret
|
||||
.align 16
|
||||
movl %ecx, vltpitch+3(%rip)
|
||||
# selfmod pm, vltpitch+6
|
||||
ret
|
||||
.align 16
|
||||
|
||||
.globl setupvlinetallasm
|
||||
.globl setupvlinetallasm
|
||||
setupvlinetallasm:
|
||||
movb %dil, shifter1+2(%rip)
|
||||
movb %dil, shifter2+2(%rip)
|
||||
movb %dil, shifter3+2(%rip)
|
||||
movb %dil, shifter4+2(%rip)
|
||||
# selfmod shifter1, shifter4+3
|
||||
movb %dil, shifter4+2(%rip)
|
||||
# selfmod shifter1, shifter4+3
|
||||
ret
|
||||
.align 16
|
||||
|
||||
.section .rtext,"awx"
|
||||
|
||||
.align 16
|
||||
|
||||
.section .rtext,"awx"
|
||||
|
||||
.globl vlinetallasm4
|
||||
.type vlinetallasm4,@function
|
||||
vlinetallasm4:
|
||||
|
@ -38,18 +38,18 @@ vlinetallasm4:
|
|||
subq $8, %rsp # Does the stack need to be 16-byte aligned for Linux?
|
||||
.cfi_adjust_cfa_offset 8
|
||||
|
||||
# rax = bufplce base address
|
||||
# rbx =
|
||||
# rcx = offset from rdi/count (negative)
|
||||
# edx/rdx = scratch
|
||||
# rdi = bottom of columns to write to
|
||||
# r8d-r11d = column offsets
|
||||
# r12-r15 = palookupoffse[0] - palookupoffse[4]
|
||||
# rax = bufplce base address
|
||||
# rbx =
|
||||
# rcx = offset from rdi/count (negative)
|
||||
# edx/rdx = scratch
|
||||
# rdi = bottom of columns to write to
|
||||
# r8d-r11d = column offsets
|
||||
# r12-r15 = palookupoffse[0] - palookupoffse[4]
|
||||
|
||||
movl dc_count(%rip), %ecx
|
||||
movq dc_dest(%rip), %rdi
|
||||
testl %ecx, %ecx
|
||||
jle vltepilog # count must be positive
|
||||
jle vltepilog # count must be positive
|
||||
|
||||
movq bufplce(%rip), %rax
|
||||
movq bufplce+8(%rip), %r8
|
||||
|
@ -60,14 +60,14 @@ vlinetallasm4:
|
|||
subq %rax, %r10
|
||||
movl %r8d, source2+4(%rip)
|
||||
movl %r9d, source3+4(%rip)
|
||||
movl %r10d, source4+4(%rip)
|
||||
movl %r10d, source4+4(%rip)
|
||||
|
||||
pm: imulq $320, %rcx
|
||||
pm: imulq $320, %rcx
|
||||
|
||||
movq palookupoffse(%rip), %r12
|
||||
movq palookupoffse+8(%rip), %r13
|
||||
movq palookupoffse+16(%rip), %r14
|
||||
movq palookupoffse+24(%rip), %r15
|
||||
movq palookupoffse+24(%rip), %r15
|
||||
|
||||
movl vince(%rip), %r8d
|
||||
movl vince+4(%rip), %r9d
|
||||
|
@ -76,53 +76,53 @@ pm: imulq $320, %rcx
|
|||
movl %r8d, step1+3(%rip)
|
||||
movl %r9d, step2+3(%rip)
|
||||
movl %r10d, step3+3(%rip)
|
||||
movl %r11d, step4+3(%rip)
|
||||
movl %r11d, step4+3(%rip)
|
||||
|
||||
addq %rcx, %rdi
|
||||
negq %rcx
|
||||
negq %rcx
|
||||
|
||||
movl vplce(%rip), %r8d
|
||||
movl vplce+4(%rip), %r9d
|
||||
movl vplce+8(%rip), %r10d
|
||||
movl vplce+12(%rip), %r11d
|
||||
# selfmod loopit, vltepilog
|
||||
jmp loopit
|
||||
jmp loopit
|
||||
|
||||
.align 16
|
||||
.align 16
|
||||
loopit:
|
||||
movl %r8d, %edx
|
||||
shifter1: shrl $24, %edx
|
||||
step1: addl $0x88888888, %r8d
|
||||
step1: addl $0x44444444, %r8d
|
||||
movzbl (%rax,%rdx), %edx
|
||||
movl %r9d, %ebx
|
||||
movb (%r12,%rdx), %dl
|
||||
shifter2: shrl $24, %ebx
|
||||
step2: addl $0x88888888, %r9d
|
||||
source2: movzbl 0x88888888(%rax,%rbx), %ebx
|
||||
step2: addl $0x44444444, %r9d
|
||||
source2: movzbl 0x44444444(%rax,%rbx), %ebx
|
||||
movl %r10d, %ebp
|
||||
movb (%r13,%rbx), %bl
|
||||
shifter3: shr $24, %ebp
|
||||
step3: addl $0x88888888, %r10d
|
||||
source3: movzbl 0x88888888(%rax,%rbp), %ebp
|
||||
step3: addl $0x44444444, %r10d
|
||||
source3: movzbl 0x44444444(%rax,%rbp), %ebp
|
||||
movl %r11d, %esi
|
||||
movb (%r14,%rbp), %bpl
|
||||
shifter4: shr $24, %esi
|
||||
step4: add $0x88888888, %r11d
|
||||
source4: movzbl 0x88888888(%rax,%rsi), %esi
|
||||
step4: add $0x44444444, %r11d
|
||||
source4: movzbl 0x44444444(%rax,%rsi), %esi
|
||||
movb %dl, (%rdi,%rcx)
|
||||
movb %bl, 1(%rdi,%rcx)
|
||||
movb (%r15,%rsi), %sil
|
||||
movb %bpl, 2(%rdi,%rcx)
|
||||
movb %sil, 3(%rdi,%rcx)
|
||||
|
||||
vltpitch: addq $320, %rcx
|
||||
jl loopit
|
||||
vltpitch: addq $320, %rcx
|
||||
jl loopit
|
||||
|
||||
movl %r8d, vplce(%rip)
|
||||
movl %r9d, vplce+4(%rip)
|
||||
movl %r10d, vplce+8(%rip)
|
||||
movl %r11d, vplce+12(%rip)
|
||||
|
||||
movl %r11d, vplce+12(%rip)
|
||||
|
||||
vltepilog:
|
||||
addq $8, %rsp
|
||||
.cfi_adjust_cfa_offset -8
|
||||
|
@ -137,5 +137,5 @@ vltepilog:
|
|||
ret
|
||||
.cfi_endproc
|
||||
.align 16
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -67,8 +67,6 @@ CCMD (removebots)
|
|||
Net_WriteByte (DEM_KILLBOTS);
|
||||
}
|
||||
|
||||
extern bool CheckCheatmode ();
|
||||
|
||||
CCMD (freeze)
|
||||
{
|
||||
if (CheckCheatmode ())
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define __forceinline inline
|
||||
#if defined(__GNUC__) && !defined(__forceinline)
|
||||
#define __forceinline __inline__ __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
static __forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
||||
|
|
934
src/c_bind.cpp
934
src/c_bind.cpp
|
@ -47,12 +47,6 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct FBinding
|
||||
{
|
||||
const char *Key;
|
||||
const char *Bind;
|
||||
};
|
||||
|
||||
/* Default keybindings for Doom (and all other games)
|
||||
*/
|
||||
static const FBinding DefBindings[] =
|
||||
|
@ -178,6 +172,29 @@ static const FBinding DefStrifeBindings[] =
|
|||
// h - use health
|
||||
};
|
||||
|
||||
static const FBinding DefAutomapBindings[] =
|
||||
{
|
||||
{ "f", "am_togglefollow" },
|
||||
{ "g", "am_togglegrid" },
|
||||
{ "p", "am_toggletexture" },
|
||||
{ "m", "am_setmark" },
|
||||
{ "c", "am_clearmarks" },
|
||||
{ "0", "am_gobig" },
|
||||
{ "rightarrow", "+am_panright" },
|
||||
{ "leftarrow", "+am_panleft" },
|
||||
{ "uparrow", "+am_panup" },
|
||||
{ "downarrow", "+am_pandown" },
|
||||
{ "-", "+am_zoomout" },
|
||||
{ "=", "+am_zoomin" },
|
||||
{ "kp-", "+am_zoomout" },
|
||||
{ "kp+", "+am_zoomin" },
|
||||
{ "mwheelup", "am_zoom 1.2" },
|
||||
{ "mwheeldown", "am_zoom -1.2" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
const char *KeyNames[NUM_KEYS] =
|
||||
{
|
||||
// This array is dependant on the particular keyboard input
|
||||
|
@ -278,11 +295,19 @@ const char *KeyNames[NUM_KEYS] =
|
|||
"pad_a", "pad_b", "pad_x", "pad_y"
|
||||
};
|
||||
|
||||
static FString Bindings[NUM_KEYS];
|
||||
static FString DoubleBindings[NUM_KEYS];
|
||||
FKeyBindings Bindings;
|
||||
FKeyBindings DoubleBindings;
|
||||
FKeyBindings AutomapBindings;
|
||||
|
||||
static unsigned int DClickTime[NUM_KEYS];
|
||||
static BYTE DClicked[(NUM_KEYS+7)/8];
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static int GetKeyFromName (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
@ -302,380 +327,15 @@ static int GetKeyFromName (const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *KeyName (int key)
|
||||
{
|
||||
static char name[5];
|
||||
|
||||
if (KeyNames[key])
|
||||
return KeyNames[key];
|
||||
|
||||
mysnprintf (name, countof(name), "#%d", key);
|
||||
return name;
|
||||
}
|
||||
|
||||
void C_UnbindAll ()
|
||||
{
|
||||
for (int i = 0; i < NUM_KEYS; ++i)
|
||||
{
|
||||
Bindings[i] = "";
|
||||
DoubleBindings[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (unbindall)
|
||||
{
|
||||
C_UnbindAll ();
|
||||
}
|
||||
|
||||
CCMD (unbind)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if ( (i = GetKeyFromName (argv[1])) )
|
||||
{
|
||||
Bindings[i] = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (bind)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], Bindings[i].GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Bindings[i] = argv[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Current key bindings:\n");
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (!Bindings[i].IsEmpty())
|
||||
Printf ("%s \"%s\"\n", KeyName (i), Bindings[i].GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//=============================================================================
|
||||
//
|
||||
// CCMD defaultbind
|
||||
//
|
||||
// Binds a command to a key if that key is not already bound and if
|
||||
// that command is not already bound to another key.
|
||||
//
|
||||
//==========================================================================
|
||||
//=============================================================================
|
||||
|
||||
CCMD (defaultbind)
|
||||
static int GetConfigKeyFromName (const char *key)
|
||||
{
|
||||
if (argv.argc() < 3)
|
||||
{
|
||||
Printf ("Usage: defaultbind <key> <command>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
int key = GetKeyFromName (argv[1]);
|
||||
if (key == 0)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (!Bindings[key].IsEmpty())
|
||||
{ // This key is already bound.
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < NUM_KEYS; ++i)
|
||||
{
|
||||
if (!Bindings[i].IsEmpty() && stricmp (Bindings[i], argv[2]) == 0)
|
||||
{ // This command is already bound to a key.
|
||||
return;
|
||||
}
|
||||
}
|
||||
// It is safe to do the bind, so do it.
|
||||
Bindings[key] = argv[2];
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (undoublebind)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if ( (i = GetKeyFromName (argv[1])) )
|
||||
{
|
||||
DoubleBindings[i] = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (doublebind)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], DoubleBindings[i].GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
DoubleBindings[i] = argv[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Current key doublebindings:\n");
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (!DoubleBindings[i].IsEmpty())
|
||||
Printf ("%s \"%s\"\n", KeyName (i), DoubleBindings[i].GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (rebind)
|
||||
{
|
||||
FString *bindings;
|
||||
|
||||
if (key == 0)
|
||||
{
|
||||
Printf ("Rebind cannot be used from the console\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (key & KEY_DBLCLICKED)
|
||||
{
|
||||
bindings = DoubleBindings;
|
||||
key &= KEY_DBLCLICKED-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindings = Bindings;
|
||||
}
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
bindings[key] = argv[1];
|
||||
}
|
||||
}
|
||||
|
||||
static void SetBinds (const FBinding *array)
|
||||
{
|
||||
while (array->Key)
|
||||
{
|
||||
C_DoBind (array->Key, array->Bind, false);
|
||||
array++;
|
||||
}
|
||||
}
|
||||
|
||||
void C_BindDefaults ()
|
||||
{
|
||||
SetBinds (DefBindings);
|
||||
|
||||
if (gameinfo.gametype & (GAME_Raven|GAME_Strife))
|
||||
{
|
||||
SetBinds (DefRavenBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Heretic)
|
||||
{
|
||||
SetBinds (DefHereticBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
SetBinds (DefHexenBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
SetBinds (DefStrifeBindings);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(binddefaults)
|
||||
{
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
void C_SetDefaultBindings ()
|
||||
{
|
||||
C_UnbindAll ();
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
bool C_DoKey (event_t *ev)
|
||||
{
|
||||
FString binding;
|
||||
bool dclick;
|
||||
int dclickspot;
|
||||
BYTE dclickmask;
|
||||
|
||||
if (ev->type != EV_KeyDown && ev->type != EV_KeyUp)
|
||||
return false;
|
||||
|
||||
if ((unsigned int)ev->data1 >= NUM_KEYS)
|
||||
return false;
|
||||
|
||||
dclickspot = ev->data1 >> 3;
|
||||
dclickmask = 1 << (ev->data1 & 7);
|
||||
dclick = false;
|
||||
|
||||
// This used level.time which didn't work outside a level.
|
||||
if (DClickTime[ev->data1] > I_MSTime() && ev->type == EV_KeyDown)
|
||||
{
|
||||
// Key pressed for a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] |= dclickmask;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{ // Key pressed for a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
DClickTime[ev->data1] = I_MSTime() + 571;
|
||||
}
|
||||
else if (DClicked[dclickspot] & dclickmask)
|
||||
{ // Key released from a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] &= ~dclickmask;
|
||||
DClickTime[ev->data1] = 0;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{ // Key released from a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (binding.IsEmpty())
|
||||
{
|
||||
binding = Bindings[ev->data1];
|
||||
dclick = false;
|
||||
}
|
||||
|
||||
if (!binding.IsEmpty() && (chatmodeon == 0 || ev->data1 < 256))
|
||||
{
|
||||
if (ev->type == EV_KeyUp && binding[0] != '+')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *copy = binding.LockBuffer();
|
||||
|
||||
if (ev->type == EV_KeyUp)
|
||||
{
|
||||
copy[0] = '-';
|
||||
}
|
||||
|
||||
AddCommandString (copy, dclick ? ev->data1 | KEY_DBLCLICKED : ev->data1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *C_ConfigKeyName(int keynum)
|
||||
{
|
||||
const char *name = KeyName(keynum);
|
||||
if (name[1] == 0) // Make sure given name is config-safe
|
||||
{
|
||||
if (name[0] == '[')
|
||||
return "LeftBracket";
|
||||
else if (name[0] == ']')
|
||||
return "RightBracket";
|
||||
else if (name[0] == '=')
|
||||
return "Equals";
|
||||
else if (strcmp (name, "kp=") == 0)
|
||||
return "KP-Equals";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// This function is first called for functions in custom key sections.
|
||||
// In this case, matchcmd is non-NULL, and only keys bound to that command
|
||||
// are stored. If a match is found, its binding is set to "\1".
|
||||
// After all custom key sections are saved, it is called one more for the
|
||||
// normal Bindings and DoubleBindings sections for this game. In this case
|
||||
// matchcmd is NULL and all keys will be stored. The config section was not
|
||||
// previously cleared, so all old bindings are still in place. If the binding
|
||||
// for a key is empty, the corresponding key in the config is removed as well.
|
||||
// If a binding is "\1", then the binding itself is cleared, but nothing
|
||||
// happens to the entry in the config.
|
||||
void C_ArchiveBindings (FConfigFile *f, bool dodouble, const char *matchcmd)
|
||||
{
|
||||
FString *bindings;
|
||||
int i;
|
||||
|
||||
bindings = dodouble ? DoubleBindings : Bindings;
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (bindings[i].IsEmpty())
|
||||
{
|
||||
if (matchcmd == NULL)
|
||||
{
|
||||
f->ClearKey(C_ConfigKeyName(i));
|
||||
}
|
||||
}
|
||||
else if (matchcmd == NULL || stricmp(bindings[i], matchcmd) == 0)
|
||||
{
|
||||
if (bindings[i][0] == '\1')
|
||||
{
|
||||
bindings[i] = "";
|
||||
continue;
|
||||
}
|
||||
f->SetValueForKey(C_ConfigKeyName(i), bindings[i]);
|
||||
if (matchcmd != NULL)
|
||||
{ // If saving a specific command, set a marker so that
|
||||
// it does not get saved in the general binding list.
|
||||
bindings[i] = "\1";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_DoBind (const char *key, const char *bind, bool dodouble)
|
||||
{
|
||||
int keynum = GetKeyFromName (key);
|
||||
int keynum = GetKeyFromName(key);
|
||||
if (keynum == 0)
|
||||
{
|
||||
if (stricmp (key, "LeftBracket") == 0)
|
||||
|
@ -695,32 +355,55 @@ void C_DoBind (const char *key, const char *bind, bool dodouble)
|
|||
keynum = GetKeyFromName ("kp=");
|
||||
}
|
||||
}
|
||||
if (keynum != 0)
|
||||
{
|
||||
(dodouble ? DoubleBindings : Bindings)[keynum] = bind;
|
||||
}
|
||||
return keynum;
|
||||
}
|
||||
|
||||
int C_GetKeysForCommand (char *cmd, int *first, int *second)
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static const char *KeyName (int key)
|
||||
{
|
||||
int c, i;
|
||||
static char name[5];
|
||||
|
||||
*first = *second = c = i = 0;
|
||||
if (KeyNames[key])
|
||||
return KeyNames[key];
|
||||
|
||||
while (i < NUM_KEYS && c < 2)
|
||||
{
|
||||
if (stricmp (cmd, Bindings[i]) == 0)
|
||||
{
|
||||
if (c++ == 0)
|
||||
*first = i;
|
||||
else
|
||||
*second = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return c;
|
||||
mysnprintf (name, countof(name), "#%d", key);
|
||||
return name;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static const char *ConfigKeyName(int keynum)
|
||||
{
|
||||
const char *name = KeyName(keynum);
|
||||
if (name[1] == 0) // Make sure given name is config-safe
|
||||
{
|
||||
if (name[0] == '[')
|
||||
return "LeftBracket";
|
||||
else if (name[0] == ']')
|
||||
return "RightBracket";
|
||||
else if (name[0] == '=')
|
||||
return "Equals";
|
||||
else if (strcmp (name, "kp=") == 0)
|
||||
return "KP-Equals";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void C_NameKeys (char *str, int first, int second)
|
||||
{
|
||||
int c = 0;
|
||||
|
@ -744,28 +427,471 @@ void C_NameKeys (char *str, int first, int second)
|
|||
*str = '\0';
|
||||
}
|
||||
|
||||
void C_UnbindACommand (char *str)
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::DoBind (const char *key, const char *bind)
|
||||
{
|
||||
int keynum = GetConfigKeyFromName (key);
|
||||
if (keynum != 0)
|
||||
{
|
||||
Binds[keynum] = bind;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::SetBinds(const FBinding *binds)
|
||||
{
|
||||
while (binds->Key)
|
||||
{
|
||||
DoBind (binds->Key, binds->Bind);
|
||||
binds++;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::UnbindAll ()
|
||||
{
|
||||
for (int i = 0; i < NUM_KEYS; ++i)
|
||||
{
|
||||
Binds[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::UnbindKey(const char *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( (i = GetKeyFromName (key)) )
|
||||
{
|
||||
Binds[i] = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::PerformBind(FCommandLine &argv, const char *msg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], Binds[i].GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Binds[i] = argv[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("%s:\n", msg);
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (!Binds[i].IsEmpty())
|
||||
Printf ("%s \"%s\"\n", KeyName (i), Binds[i].GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// This function is first called for functions in custom key sections.
|
||||
// In this case, matchcmd is non-NULL, and only keys bound to that command
|
||||
// are stored. If a match is found, its binding is set to "\1".
|
||||
// After all custom key sections are saved, it is called one more for the
|
||||
// normal Bindings and DoubleBindings sections for this game. In this case
|
||||
// matchcmd is NULL and all keys will be stored. The config section was not
|
||||
// previously cleared, so all old bindings are still in place. If the binding
|
||||
// for a key is empty, the corresponding key in the config is removed as well.
|
||||
// If a binding is "\1", then the binding itself is cleared, but nothing
|
||||
// happens to the entry in the config.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::ArchiveBindings(FConfigFile *f, const char *matchcmd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (!stricmp (str, Bindings[i]))
|
||||
if (Binds[i].IsEmpty())
|
||||
{
|
||||
Bindings[i] = "";
|
||||
if (matchcmd == NULL)
|
||||
{
|
||||
f->ClearKey(ConfigKeyName(i));
|
||||
}
|
||||
}
|
||||
else if (matchcmd == NULL || stricmp(Binds[i], matchcmd) == 0)
|
||||
{
|
||||
if (Binds[i][0] == '\1')
|
||||
{
|
||||
Binds[i] = "";
|
||||
continue;
|
||||
}
|
||||
f->SetValueForKey(ConfigKeyName(i), Binds[i]);
|
||||
if (matchcmd != NULL)
|
||||
{ // If saving a specific command, set a marker so that
|
||||
// it does not get saved in the general binding list.
|
||||
Binds[i] = "\1";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_ChangeBinding (const char *str, int newone)
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
int FKeyBindings::GetKeysForCommand (char *cmd, int *first, int *second)
|
||||
{
|
||||
if ((unsigned int)newone < NUM_KEYS)
|
||||
int c, i;
|
||||
|
||||
*first = *second = c = i = 0;
|
||||
|
||||
while (i < NUM_KEYS && c < 2)
|
||||
{
|
||||
Bindings[newone] = str;
|
||||
if (stricmp (cmd, Binds[i]) == 0)
|
||||
{
|
||||
if (c++ == 0)
|
||||
*first = i;
|
||||
else
|
||||
*second = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::UnbindACommand (char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (!stricmp (str, Binds[i]))
|
||||
{
|
||||
Binds[i] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *C_GetBinding (int key)
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FKeyBindings::DefaultBind(const char *keyname, const char *cmd)
|
||||
{
|
||||
return (unsigned int)key < NUM_KEYS ? Bindings[key].GetChars() : NULL;
|
||||
int key = GetKeyFromName (keyname);
|
||||
if (key == 0)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", keyname);
|
||||
return;
|
||||
}
|
||||
if (!Binds[key].IsEmpty())
|
||||
{ // This key is already bound.
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < NUM_KEYS; ++i)
|
||||
{
|
||||
if (!Binds[i].IsEmpty() && stricmp (Binds[i], cmd) == 0)
|
||||
{ // This command is already bound to a key.
|
||||
return;
|
||||
}
|
||||
}
|
||||
// It is safe to do the bind, so do it.
|
||||
Binds[key] = cmd;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void C_UnbindAll ()
|
||||
{
|
||||
Bindings.UnbindAll();
|
||||
DoubleBindings.UnbindAll();
|
||||
AutomapBindings.UnbindAll();
|
||||
}
|
||||
|
||||
CCMD (unbindall)
|
||||
{
|
||||
C_UnbindAll ();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
CCMD (unbind)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
Bindings.UnbindKey(argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (undoublebind)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
DoubleBindings.UnbindKey(argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (unmapbind)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
AutomapBindings.UnbindKey(argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
CCMD (bind)
|
||||
{
|
||||
Bindings.PerformBind(argv, "Current key bindings");
|
||||
}
|
||||
|
||||
CCMD (doublebind)
|
||||
{
|
||||
DoubleBindings.PerformBind(argv, "Current key doublebindings");
|
||||
}
|
||||
|
||||
CCMD (mapbind)
|
||||
{
|
||||
AutomapBindings.PerformBind(argv, "Current automap key bindings");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CCMD defaultbind
|
||||
//
|
||||
// Binds a command to a key if that key is not already bound and if
|
||||
// that command is not already bound to another key.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD (defaultbind)
|
||||
{
|
||||
if (argv.argc() < 3)
|
||||
{
|
||||
Printf ("Usage: defaultbind <key> <command>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Bindings.DefaultBind(argv[1], argv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
CCMD (rebind)
|
||||
{
|
||||
FKeyBindings *bindings;
|
||||
|
||||
if (key == 0)
|
||||
{
|
||||
Printf ("Rebind cannot be used from the console\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (key & KEY_DBLCLICKED)
|
||||
{
|
||||
bindings = &DoubleBindings;
|
||||
key &= KEY_DBLCLICKED-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindings = &Bindings;
|
||||
}
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
bindings->SetBind(key, argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void C_BindDefaults ()
|
||||
{
|
||||
Bindings.SetBinds (DefBindings);
|
||||
|
||||
if (gameinfo.gametype & (GAME_Raven|GAME_Strife))
|
||||
{
|
||||
Bindings.SetBinds (DefRavenBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Heretic)
|
||||
{
|
||||
Bindings.SetBinds (DefHereticBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
Bindings.SetBinds (DefHexenBindings);
|
||||
}
|
||||
|
||||
if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
Bindings.SetBinds (DefStrifeBindings);
|
||||
}
|
||||
|
||||
AutomapBindings.SetBinds(DefAutomapBindings);
|
||||
}
|
||||
|
||||
CCMD(binddefaults)
|
||||
{
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
void C_SetDefaultBindings ()
|
||||
{
|
||||
C_UnbindAll ();
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds)
|
||||
{
|
||||
FString binding;
|
||||
bool dclick;
|
||||
int dclickspot;
|
||||
BYTE dclickmask;
|
||||
|
||||
if (ev->type != EV_KeyDown && ev->type != EV_KeyUp)
|
||||
return false;
|
||||
|
||||
if ((unsigned int)ev->data1 >= NUM_KEYS)
|
||||
return false;
|
||||
|
||||
dclickspot = ev->data1 >> 3;
|
||||
dclickmask = 1 << (ev->data1 & 7);
|
||||
dclick = false;
|
||||
|
||||
// This used level.time which didn't work outside a level.
|
||||
if (DClickTime[ev->data1] > I_MSTime() && ev->type == EV_KeyDown)
|
||||
{
|
||||
// Key pressed for a double click
|
||||
if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1);
|
||||
DClicked[dclickspot] |= dclickmask;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{ // Key pressed for a normal press
|
||||
binding = binds->GetBinding(ev->data1);
|
||||
DClickTime[ev->data1] = I_MSTime() + 571;
|
||||
}
|
||||
else if (DClicked[dclickspot] & dclickmask)
|
||||
{ // Key released from a double click
|
||||
if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1);
|
||||
DClicked[dclickspot] &= ~dclickmask;
|
||||
DClickTime[ev->data1] = 0;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{ // Key released from a normal press
|
||||
binding = binds->GetBinding(ev->data1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (binding.IsEmpty())
|
||||
{
|
||||
binding = binds->GetBinding(ev->data1);
|
||||
dclick = false;
|
||||
}
|
||||
|
||||
if (!binding.IsEmpty() && (chatmodeon == 0 || ev->data1 < 256))
|
||||
{
|
||||
if (ev->type == EV_KeyUp && binding[0] != '+')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *copy = binding.LockBuffer();
|
||||
|
||||
if (ev->type == EV_KeyUp)
|
||||
{
|
||||
copy[0] = '-';
|
||||
}
|
||||
|
||||
AddCommandString (copy, dclick ? ev->data1 | KEY_DBLCLICKED : ev->data1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
60
src/c_bind.h
60
src/c_bind.h
|
@ -34,25 +34,65 @@
|
|||
#ifndef __C_BINDINGS_H__
|
||||
#define __C_BINDINGS_H__
|
||||
|
||||
#include "doomdef.h"
|
||||
|
||||
struct event_t;
|
||||
class FConfigFile;
|
||||
class FCommandLine;
|
||||
|
||||
bool C_DoKey (event_t *ev);
|
||||
void C_ArchiveBindings (FConfigFile *f, bool dodouble, const char *matchcmd=NULL);
|
||||
void C_NameKeys (char *str, int first, int second);
|
||||
|
||||
struct FBinding
|
||||
{
|
||||
const char *Key;
|
||||
const char *Bind;
|
||||
};
|
||||
|
||||
class FKeyBindings
|
||||
{
|
||||
FString Binds[NUM_KEYS];
|
||||
|
||||
public:
|
||||
void PerformBind(FCommandLine &argv, const char *msg);
|
||||
void SetBinds(const FBinding *binds);
|
||||
bool DoKey(event_t *ev);
|
||||
void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL);
|
||||
int GetKeysForCommand (char *cmd, int *first, int *second);
|
||||
void UnbindACommand (char *str);
|
||||
void UnbindAll ();
|
||||
void UnbindKey(const char *key);
|
||||
void DoBind (const char *key, const char *bind);
|
||||
void DefaultBind(const char *keyname, const char *cmd);
|
||||
|
||||
void SetBind(unsigned int key, const char *bind)
|
||||
{
|
||||
if (key < NUM_KEYS) Binds[key] = bind;
|
||||
}
|
||||
|
||||
const FString &GetBinding(unsigned int index) const
|
||||
{
|
||||
return Binds[index];
|
||||
}
|
||||
|
||||
const char *GetBind(unsigned int index) const
|
||||
{
|
||||
if (index < NUM_KEYS) return Binds[index];
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern FKeyBindings Bindings;
|
||||
extern FKeyBindings DoubleBindings;
|
||||
extern FKeyBindings AutomapBindings;
|
||||
|
||||
|
||||
bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds);
|
||||
|
||||
// Stuff used by the customize controls menu
|
||||
int C_GetKeysForCommand (char *cmd, int *first, int *second);
|
||||
void C_NameKeys (char *str, int first, int second);
|
||||
void C_UnbindACommand (char *str);
|
||||
void C_ChangeBinding (const char *str, int newone);
|
||||
void C_DoBind (const char *key, const char *bind, bool doublebind);
|
||||
void C_SetDefaultBindings ();
|
||||
void C_UnbindAll ();
|
||||
|
||||
// Returns string bound to given key (NULL if none)
|
||||
const char *C_GetBinding (int key);
|
||||
|
||||
extern const char *KeyNames[];
|
||||
|
||||
#endif //__C_BINDINGS_H__
|
||||
|
|
|
@ -80,11 +80,11 @@ CCMD (toggleconsole)
|
|||
C_ToggleConsole();
|
||||
}
|
||||
|
||||
bool CheckCheatmode ()
|
||||
bool CheckCheatmode (bool printmsg)
|
||||
{
|
||||
if ((G_SkillProperty(SKILLP_DisableCheats) || netgame || deathmatch) && (!sv_cheats))
|
||||
{
|
||||
Printf ("sv_cheats must be true to enable this command.\n");
|
||||
if (printmsg) Printf ("sv_cheats must be true to enable this command.\n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -119,7 +119,9 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
|||
Button_Forward, Button_Right, Button_Left, Button_MoveDown,
|
||||
Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch,
|
||||
Button_Zoom, Button_Reload,
|
||||
Button_User1, Button_User2, Button_User3, Button_User4;
|
||||
Button_User1, Button_User2, Button_User3, Button_User4,
|
||||
Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp,
|
||||
Button_AM_ZoomIn, Button_AM_ZoomOut;
|
||||
|
||||
bool ParsingKeyConf;
|
||||
|
||||
|
@ -131,13 +133,16 @@ bool ParsingKeyConf;
|
|||
|
||||
FActionMap ActionMaps[] =
|
||||
{
|
||||
{ 0x0d52d67b, &Button_AM_PanLeft, "am_panleft"},
|
||||
{ 0x125f5226, &Button_User2, "user2" },
|
||||
{ 0x1eefa611, &Button_Jump, "jump" },
|
||||
{ 0x201f1c55, &Button_Right, "right" },
|
||||
{ 0x20ccc4d5, &Button_Zoom, "zoom" },
|
||||
{ 0x23a99cd7, &Button_Back, "back" },
|
||||
{ 0x41df90c2, &Button_AM_ZoomIn, "am_zoomin"},
|
||||
{ 0x426b69e7, &Button_Reload, "reload" },
|
||||
{ 0x4463f43a, &Button_LookDown, "lookdown" },
|
||||
{ 0x51f7a334, &Button_AM_ZoomOut, "am_zoomout"},
|
||||
{ 0x534c30ee, &Button_User4, "user4" },
|
||||
{ 0x5622bf42, &Button_Attack, "attack" },
|
||||
{ 0x577712d0, &Button_User1, "user1" },
|
||||
|
@ -147,12 +152,15 @@ FActionMap ActionMaps[] =
|
|||
{ 0x676885b8, &Button_AltAttack, "altattack" },
|
||||
{ 0x6fa41b84, &Button_MoveLeft, "moveleft" },
|
||||
{ 0x818f08e6, &Button_MoveRight, "moveright" },
|
||||
{ 0x8197097b, &Button_AM_PanRight, "am_panright"},
|
||||
{ 0x8d89955e, &Button_AM_PanUp, "am_panup"} ,
|
||||
{ 0xa2b62d8b, &Button_Mlook, "mlook" },
|
||||
{ 0xab2c3e71, &Button_Crouch, "crouch" },
|
||||
{ 0xb000b483, &Button_Left, "left" },
|
||||
{ 0xb62b1e49, &Button_LookUp, "lookup" },
|
||||
{ 0xb6f8fe92, &Button_User3, "user3" },
|
||||
{ 0xb7e6a54b, &Button_Strafe, "strafe" },
|
||||
{ 0xce301c81, &Button_AM_PanDown, "am_pandown"},
|
||||
{ 0xd5897c73, &Button_ShowScores, "showscores" },
|
||||
{ 0xe0ccb317, &Button_Speed, "speed" },
|
||||
{ 0xe0cfc260, &Button_Use, "use" },
|
||||
|
@ -160,6 +168,7 @@ FActionMap ActionMaps[] =
|
|||
};
|
||||
#define NUM_ACTIONS countof(ActionMaps)
|
||||
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static const char *KeyConfCommands[] =
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
class FConfigFile;
|
||||
class APlayerPawn;
|
||||
|
||||
extern bool CheckCheatmode (bool printmsg = true);
|
||||
|
||||
void C_ExecCmdLineParams ();
|
||||
|
||||
// Add commands to the console as if they were typed in. Can handle wait
|
||||
|
@ -144,6 +146,7 @@ struct FButtonStatus
|
|||
bool PressKey (int keynum); // Returns true if this key caused the button to be pressed.
|
||||
bool ReleaseKey (int keynum); // Returns true if this key is no longer pressed.
|
||||
void ResetTriggers () { bWentDown = bWentUp = false; }
|
||||
void Reset () { bDown = bWentDown = bWentUp = false; }
|
||||
};
|
||||
|
||||
extern FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
||||
|
@ -152,7 +155,9 @@ extern FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
|||
Button_Forward, Button_Right, Button_Left, Button_MoveDown,
|
||||
Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch,
|
||||
Button_Zoom, Button_Reload,
|
||||
Button_User1, Button_User2, Button_User3, Button_User4;
|
||||
Button_User1, Button_User2, Button_User3, Button_User4,
|
||||
Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp,
|
||||
Button_AM_ZoomIn, Button_AM_ZoomOut;
|
||||
extern bool ParsingKeyConf;
|
||||
|
||||
void ResetButtonTriggers (); // Call ResetTriggers for all buttons
|
||||
|
|
171
src/cmdlib.cpp
171
src/cmdlib.cpp
|
@ -2,10 +2,14 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#if !defined(__sun)
|
||||
#include <fts.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "doomtype.h"
|
||||
#include "cmdlib.h"
|
||||
|
@ -90,6 +94,23 @@ char *copystring (const char *s)
|
|||
return b;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// ncopystring
|
||||
//
|
||||
// If the string has no content, returns NULL. Otherwise, returns a copy.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
char *ncopystring (const char *string)
|
||||
{
|
||||
if (string == NULL || string[0] == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return copystring (string);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ReplaceString
|
||||
|
@ -868,3 +889,153 @@ FString NicePath(const char *path)
|
|||
return where;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
struct _finddata_t fileinfo;
|
||||
intptr_t handle;
|
||||
FString dirmatch;
|
||||
|
||||
dirmatch << dirpath << "*";
|
||||
|
||||
if ((handle = _findfirst(dirmatch, &fileinfo)) == -1)
|
||||
{
|
||||
I_Error("Could not scan '%s': %s\n", dirpath, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (fileinfo.attrib & _A_HIDDEN)
|
||||
{
|
||||
// Skip hidden files and directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileinfo.attrib & _A_SUBDIR)
|
||||
{
|
||||
if (fileinfo.name[0] == '.' &&
|
||||
(fileinfo.name[1] == '\0' ||
|
||||
(fileinfo.name[1] == '.' && fileinfo.name[2] == '\0')))
|
||||
{
|
||||
// Do not record . and .. directories.
|
||||
continue;
|
||||
}
|
||||
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fileinfo.name;
|
||||
fl->isDirectory = true;
|
||||
FString newdir = fl->Filename;
|
||||
newdir << "/";
|
||||
ScanDirectory(list, newdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fileinfo.name;
|
||||
fl->isDirectory = false;
|
||||
}
|
||||
}
|
||||
while (_findnext(handle, &fileinfo) == 0);
|
||||
_findclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__sun) || defined(linux)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
// Solaris version
|
||||
//
|
||||
// Given NULL-terminated array of directory paths, create trees for them.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
DIR *directory = opendir(dirpath);
|
||||
if(directory == NULL)
|
||||
return;
|
||||
|
||||
struct dirent *file;
|
||||
while((file = readdir(directory)) != NULL)
|
||||
{
|
||||
if(file->d_name[0] == '.') //File is hidden or ./.. directory so ignore it.
|
||||
continue;
|
||||
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << file->d_name;
|
||||
|
||||
struct stat fileStat;
|
||||
stat(fl->Filename, &fileStat);
|
||||
fl->isDirectory = S_ISDIR(fileStat.st_mode);
|
||||
|
||||
if(fl->isDirectory)
|
||||
{
|
||||
FString newdir = fl->Filename;
|
||||
newdir += "/";
|
||||
ScanDirectory(list, newdir);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(directory);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
// 4.4BSD version
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
const char **argv[] = {dirpath, NULL };
|
||||
FTS *fts;
|
||||
FTSENT *ent;
|
||||
|
||||
fts = fts_open(argv, FTS_LOGICAL, NULL);
|
||||
if (fts == NULL)
|
||||
{
|
||||
I_Error("Failed to start directory traversal: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
while ((ent = fts_read(fts)) != NULL)
|
||||
{
|
||||
if (ent->fts_info == FTS_D && ent->fts_name[0] == '.')
|
||||
{
|
||||
// Skip hidden directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
fts_set(fts, ent, FTS_SKIP);
|
||||
}
|
||||
if (ent->fts_info == FTS_D && ent->fts_level == 0)
|
||||
{
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename = ent->fts_path;
|
||||
fl->isDirectory = true;
|
||||
}
|
||||
if (ent->fts_info == FTS_F)
|
||||
{
|
||||
// We're only interested in remembering files.
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename = ent->fts_path;
|
||||
fl->isDirectory = false;
|
||||
}
|
||||
}
|
||||
fts_close(fts);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@ int ParseNum (const char *str);
|
|||
bool IsNum (const char *str); // [RH] added
|
||||
|
||||
char *copystring(const char *s);
|
||||
char *ncopystring(const char *s);
|
||||
void ReplaceString (char **ptr, const char *str);
|
||||
|
||||
bool CheckWildcards (const char *pattern, const char *text);
|
||||
|
@ -53,4 +54,12 @@ void CreatePath(const char * fn);
|
|||
FString ExpandEnvVars(const char *searchpathstring);
|
||||
FString NicePath(const char *path);
|
||||
|
||||
struct FFileList
|
||||
{
|
||||
FString Filename;
|
||||
bool isDirectory;
|
||||
};
|
||||
|
||||
void ScanDirectory(TArray<FFileList> &list, const char *dirpath);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,10 +43,13 @@
|
|||
#include "sc_man.h"
|
||||
#include "cmdlib.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "gi.h"
|
||||
#include "g_level.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "r_state.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -59,6 +62,14 @@ struct FCompatOption
|
|||
int BCompatFlags;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CP_END,
|
||||
CP_CLEARFLAGS,
|
||||
CP_SETFLAGS,
|
||||
CP_SETSPECIAL
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
@ -77,7 +88,6 @@ static FCompatOption Options[] =
|
|||
{
|
||||
{ "setslopeoverflow", 0, BCOMPATF_SETSLOPEOVERFLOW },
|
||||
{ "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED },
|
||||
{ "spechitoverflow", 0, BCOMPATF_SPECHITOVERFLOW },
|
||||
{ "vileghosts", 0, BCOMPATF_VILEGHOSTS },
|
||||
|
||||
// list copied from g_mapinfo.cpp
|
||||
|
@ -106,9 +116,15 @@ static FCompatOption Options[] =
|
|||
{ "corpsegibs", COMPATF_CORPSEGIBS, 0 },
|
||||
{ "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 },
|
||||
{ "spritesort", COMPATF_SPRITESORT, 0 },
|
||||
{ "hitscan", COMPATF_HITSCAN, 0 },
|
||||
{ "lightlevel", COMPATF_LIGHT, 0 },
|
||||
{ "polyobj", COMPATF_POLYOBJ, 0 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
static TArray<int> CompatParams;
|
||||
static int ii_compatparams;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
|
@ -170,12 +186,57 @@ void ParseCompatibility()
|
|||
} while (!sc.Compare("{"));
|
||||
flags.CompatFlags = 0;
|
||||
flags.BCompatFlags = 0;
|
||||
while (sc.MustGetString(), (i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0)
|
||||
flags.ExtCommandIndex = ~0u;
|
||||
while (sc.GetString())
|
||||
{
|
||||
flags.CompatFlags |= Options[i].CompatFlags;
|
||||
flags.BCompatFlags |= Options[i].BCompatFlags;
|
||||
if ((i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0)
|
||||
{
|
||||
flags.CompatFlags |= Options[i].CompatFlags;
|
||||
flags.BCompatFlags |= Options[i].BCompatFlags;
|
||||
}
|
||||
else if (sc.Compare("clearlineflags"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_CLEARFLAGS);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
else if (sc.Compare("setlineflags"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_SETFLAGS);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
else if (sc.Compare("setlinespecial"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_SETSPECIAL);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
|
||||
sc.MustGetString();
|
||||
CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL));
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.UnGet();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flags.ExtCommandIndex != ~0u)
|
||||
{
|
||||
CompatParams.Push(CP_END);
|
||||
}
|
||||
sc.UnGet();
|
||||
sc.MustGetStringName("}");
|
||||
for (j = 0; j < md5array.Size(); ++j)
|
||||
{
|
||||
|
@ -196,12 +257,29 @@ void CheckCompatibility(MapData *map)
|
|||
FMD5Holder md5;
|
||||
FCompatValues *flags;
|
||||
|
||||
// When playing Doom IWAD levels force COMPAT_SHORTTEX.
|
||||
// When playing Doom IWAD levels force COMPAT_SHORTTEX and COMPATF_LIGHT.
|
||||
// I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt.
|
||||
// TNT's MAP31 also needs COMPATF_STAIRINDEX but that only gets activated for TNT.WAD.
|
||||
if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATSHORTTEX) && !(level.flags & LEVEL_HEXENFORMAT))
|
||||
{
|
||||
ii_compatflags = COMPATF_SHORTTEX;
|
||||
ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT;
|
||||
if (gameinfo.flags & GI_COMPATSTAIRS) ii_compatflags |= COMPATF_STAIRINDEX;
|
||||
ib_compatflags = 0;
|
||||
ii_compatparams = -1;
|
||||
}
|
||||
else if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATPOLY1) && Wads.CheckLumpName(map->lumpnum, "MAP36"))
|
||||
{
|
||||
ii_compatflags = COMPATF_POLYOBJ;
|
||||
ib_compatflags = 0;
|
||||
ii_compatparams = -1;
|
||||
}
|
||||
else if (Wads.GetLumpFile(map->lumpnum) == 2 && (gameinfo.flags & GI_COMPATPOLY2) && Wads.CheckLumpName(map->lumpnum, "MAP47"))
|
||||
{
|
||||
ii_compatflags = COMPATF_POLYOBJ;
|
||||
ib_compatflags = 0;
|
||||
ii_compatparams = -1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
map->GetChecksum(md5.Bytes);
|
||||
|
@ -223,17 +301,74 @@ void CheckCompatibility(MapData *map)
|
|||
{
|
||||
ii_compatflags = flags->CompatFlags;
|
||||
ib_compatflags = flags->BCompatFlags;
|
||||
ii_compatparams = flags->ExtCommandIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
ii_compatflags = 0;
|
||||
ib_compatflags = 0;
|
||||
ii_compatparams = -1;
|
||||
}
|
||||
}
|
||||
// Reset i_compatflags
|
||||
compatflags.Callback();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetCompatibilityParams
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SetCompatibilityParams()
|
||||
{
|
||||
if (ii_compatparams != -1)
|
||||
{
|
||||
unsigned i = ii_compatparams;
|
||||
|
||||
while (CompatParams[i] != CP_END && i < CompatParams.Size())
|
||||
{
|
||||
switch (CompatParams[i])
|
||||
{
|
||||
case CP_CLEARFLAGS:
|
||||
{
|
||||
if (CompatParams[i+1] < numlines)
|
||||
{
|
||||
line_t *line = &lines[CompatParams[i+1]];
|
||||
line->flags &= ~CompatParams[i+2];
|
||||
}
|
||||
i+=3;
|
||||
break;
|
||||
}
|
||||
case CP_SETFLAGS:
|
||||
{
|
||||
if (CompatParams[i+1] < numlines)
|
||||
{
|
||||
line_t *line = &lines[CompatParams[i+1]];
|
||||
line->flags |= CompatParams[i+2];
|
||||
}
|
||||
i+=3;
|
||||
break;
|
||||
}
|
||||
case CP_SETSPECIAL:
|
||||
{
|
||||
if (CompatParams[i+1] < numlines)
|
||||
{
|
||||
line_t *line = &lines[CompatParams[i+1]];
|
||||
line->special = CompatParams[i+2];
|
||||
for(int ii=0;ii<5;ii++)
|
||||
{
|
||||
line->args[ii] = CompatParams[i+ii+3];
|
||||
}
|
||||
}
|
||||
i+=8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CCMD mapchecksum
|
||||
|
|
|
@ -16,6 +16,7 @@ struct FCompatValues
|
|||
{
|
||||
int CompatFlags;
|
||||
int BCompatFlags;
|
||||
unsigned int ExtCommandIndex;
|
||||
};
|
||||
|
||||
struct FMD5HashTraits
|
||||
|
@ -37,5 +38,6 @@ extern TMap<FMD5Holder, FCompatValues, FMD5HashTraits> BCompatMap;
|
|||
|
||||
void ParseCompatibility();
|
||||
void CheckCompatibility(MapData *map);
|
||||
void SetCompatibilityParams();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -953,7 +953,7 @@ static int PatchThing (int thingy)
|
|||
// compatibility, the upper bits are freed, but we have conflicts between the ZDoom bits
|
||||
// and the MBF bits. The only such flag exposed to DEHSUPP, though, is STEALTH -- the others
|
||||
// are not available through mnemonics, and aren't available either through their bit value.
|
||||
// So if we find the STEALTH keyword, it's a ZDoom mod, otherwise assume assume FRIEND.
|
||||
// So if we find the STEALTH keyword, it's a ZDoom mod, otherwise assume FRIEND.
|
||||
bool zdoomflags = false;
|
||||
char *strval;
|
||||
|
||||
|
@ -1355,8 +1355,8 @@ static int PatchFrame (int frameNum)
|
|||
}
|
||||
info->Tics = tics;
|
||||
info->Misc1 = misc1;
|
||||
info->Frame = (frame & 0x3f) |
|
||||
(frame & 0x8000 ? SF_FULLBRIGHT : 0);
|
||||
info->Frame = frame & 0x3f;
|
||||
info->Fullbright = frame & 0x8000 ? true : false;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -2106,13 +2106,13 @@ static int PatchText (int oldSize)
|
|||
// This must be done because the map is scanned using a binary search.
|
||||
while (i > 0 && strncmp (DehSpriteMappings[i-1].Sprite, newStr, 4) > 0)
|
||||
{
|
||||
swap (DehSpriteMappings[i-1], DehSpriteMappings[i]);
|
||||
swapvalues (DehSpriteMappings[i-1], DehSpriteMappings[i]);
|
||||
--i;
|
||||
}
|
||||
while ((size_t)i < countof(DehSpriteMappings)-1 &&
|
||||
strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0)
|
||||
{
|
||||
swap (DehSpriteMappings[i+1], DehSpriteMappings[i]);
|
||||
swapvalues (DehSpriteMappings[i+1], DehSpriteMappings[i]);
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -58,10 +58,10 @@ EIWADType gameiwad;
|
|||
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
|
||||
{
|
||||
// banner text, autoname, fg color, bg color
|
||||
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx | GI_COMPATSHORTTEX },
|
||||
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx | GI_COMPATSHORTTEX | GI_COMPATSTAIRS },
|
||||
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx | GI_COMPATSHORTTEX },
|
||||
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
|
||||
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
|
||||
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_COMPATPOLY1 },
|
||||
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_COMPATPOLY1 | GI_COMPATPOLY2 },
|
||||
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_SHAREWARE },
|
||||
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx | GI_COMPATSHORTTEX },
|
||||
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#endif
|
||||
#include <float.h>
|
||||
|
||||
#ifdef unix
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -104,6 +104,7 @@
|
|||
#include "compatibility.h"
|
||||
#include "m_joy.h"
|
||||
#include "sc_man.h"
|
||||
#include "po_man.h"
|
||||
#include "resourcefiles/resourcefile.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
|
@ -120,7 +121,6 @@ extern void M_SetDefaultMode ();
|
|||
extern void R_ExecuteSetViewSize ();
|
||||
extern void G_NewInit ();
|
||||
extern void SetupPlayerClasses ();
|
||||
extern bool CheckCheatmode ();
|
||||
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
@ -201,6 +201,7 @@ gamestate_t wipegamestate = GS_DEMOSCREEN; // can be -1 to force a wipe
|
|||
bool PageBlank;
|
||||
FTexture *Page;
|
||||
FTexture *Advisory;
|
||||
bool nospriterename;
|
||||
|
||||
cycle_t FrameCycles;
|
||||
|
||||
|
@ -459,6 +460,8 @@ CVAR (Flag, sv_disallowspying, dmflags2, DF2_DISALLOW_SPYING);
|
|||
CVAR (Flag, sv_chasecam, dmflags2, DF2_CHASECAM);
|
||||
CVAR (Flag, sv_disallowsuicide, dmflags2, DF2_NOSUICIDE);
|
||||
CVAR (Flag, sv_noautoaim, dmflags2, DF2_NOAUTOAIM);
|
||||
CVAR (Flag, sv_dontcheckammo, dmflags2, DF2_DONTCHECKAMMO);
|
||||
CVAR (Flag, sv_killbossmonst, dmflags2, DF2_KILLBOSSMONST);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -479,7 +482,12 @@ static int GetCompatibility(int mask)
|
|||
|
||||
CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
{
|
||||
int old = i_compatflags;
|
||||
i_compatflags = GetCompatibility(self) | ii_compatflags;
|
||||
if ((old ^i_compatflags) & COMPATF_POLYOBJ)
|
||||
{
|
||||
FPolyObj::ClearAllSubsectorLinks();
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
|
@ -495,28 +503,35 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
|
||||
case 1: // Doom2.exe compatible with a few relaxed settings
|
||||
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
|
||||
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF;
|
||||
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF|
|
||||
COMPATF_LIGHT;
|
||||
break;
|
||||
|
||||
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set)
|
||||
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
|
||||
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
|
||||
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS;
|
||||
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|
|
||||
COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT;
|
||||
break;
|
||||
|
||||
case 3: // Boom compat mode
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL;
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP;
|
||||
break;
|
||||
|
||||
case 4: // Old ZDoom compat mode
|
||||
v = COMPATF_SOUNDTARGET;
|
||||
v = COMPATF_SOUNDTARGET|COMPATF_LIGHT;
|
||||
break;
|
||||
|
||||
case 5: // MBF compat mode
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MUSHROOM|
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_MUSHROOM|
|
||||
COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS;
|
||||
break;
|
||||
|
||||
case 6: // Boom with some added settings to reenable spme 'broken' behavior
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ|
|
||||
COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS;
|
||||
break;
|
||||
|
||||
}
|
||||
compatflags = v;
|
||||
}
|
||||
|
@ -549,6 +564,9 @@ CVAR (Flag, compat_mbfmonstermove,compatflags, COMPATF_MBFMONSTERMOVE);
|
|||
CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS);
|
||||
CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS);
|
||||
CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT);
|
||||
CVAR (Flag, compat_hitscan, compatflags,COMPATF_HITSCAN);
|
||||
CVAR (Flag, compat_light, compatflags,COMPATF_LIGHT);
|
||||
CVAR (Flag, compat_polyobj, compatflags,COMPATF_POLYOBJ);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -1199,8 +1217,11 @@ void D_DoAdvanceDemo (void)
|
|||
case 2:
|
||||
pagetic = (int)(gameinfo.pageTime * TICRATE);
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = gameinfo.creditPages[pagecount];
|
||||
pagecount = (pagecount+1) % gameinfo.creditPages.Size();
|
||||
if (gameinfo.creditPages.Size() > 0)
|
||||
{
|
||||
pagename = gameinfo.creditPages[pagecount];
|
||||
pagecount = (pagecount+1) % gameinfo.creditPages.Size();
|
||||
}
|
||||
demosequence = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1658,6 +1679,10 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
|
|||
}
|
||||
while (sc.CheckToken(','));
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("NOSPRITERENAME"))
|
||||
{
|
||||
nospriterename = true;
|
||||
}
|
||||
}
|
||||
return iwad;
|
||||
}
|
||||
|
@ -1754,6 +1779,9 @@ void D_DoomMain (void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Check response files before coalescing file parameters.
|
||||
M_FindResponseFile ();
|
||||
|
||||
PClass::StaticInit();
|
||||
PType::StaticInit();
|
||||
|
||||
|
@ -1772,7 +1800,6 @@ void D_DoomMain (void)
|
|||
|
||||
rngseed = I_MakeRNGSeed();
|
||||
FRandom::StaticClearRandom ();
|
||||
M_FindResponseFile ();
|
||||
|
||||
Printf ("M_LoadDefaults: Load system defaults.\n");
|
||||
M_LoadDefaults (); // load before initing other systems
|
||||
|
@ -2274,6 +2301,14 @@ void FStartupScreen::AppendStatusLine(const char *status)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// STAT fps
|
||||
//
|
||||
// Displays statistics about rendering times
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ADD_STAT (fps)
|
||||
{
|
||||
FString out;
|
||||
|
@ -2282,6 +2317,24 @@ ADD_STAT (fps)
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
static double f_acc, w_acc,p_acc,m_acc;
|
||||
static int acc_c;
|
||||
|
||||
ADD_STAT (fps_accumulated)
|
||||
{
|
||||
f_acc += FrameCycles.TimeMS();
|
||||
w_acc += WallCycles.TimeMS();
|
||||
p_acc += PlaneCycles.TimeMS();
|
||||
m_acc += MaskedCycles.TimeMS();
|
||||
acc_c++;
|
||||
FString out;
|
||||
out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms %d counts",
|
||||
f_acc/acc_c, w_acc/acc_c, p_acc/acc_c, m_acc/acc_c, acc_c);
|
||||
Printf(PRINT_LOG, "%s\n", out.GetChars());
|
||||
return out;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// STAT wallcycles
|
||||
|
|
|
@ -1917,6 +1917,22 @@ BYTE *FDynamicBuffer::GetData (int *len)
|
|||
}
|
||||
|
||||
|
||||
static int KillAll(const PClass *cls)
|
||||
{
|
||||
AActor *actor;
|
||||
int killcount = 0;
|
||||
TThinkerIterator<AActor> iterator(cls);
|
||||
while ( (actor = iterator.Next ()) )
|
||||
{
|
||||
if (actor->IsA(cls))
|
||||
{
|
||||
if (!(actor->flags2 & MF2_DORMANT) && (actor->flags3 & MF3_ISMONSTER))
|
||||
killcount += actor->Massacre ();
|
||||
}
|
||||
}
|
||||
return killcount;
|
||||
|
||||
}
|
||||
// [RH] Execute a special "ticcmd". The type byte should
|
||||
// have already been read, and the stream is positioned
|
||||
// at the beginning of the command's actual data.
|
||||
|
@ -2021,7 +2037,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
// Using LEVEL_NOINTERMISSION tends to throw the game out of sync.
|
||||
// That was a long time ago. Maybe it works now?
|
||||
level.flags |= LEVEL_CHANGEMAPCHEAT;
|
||||
G_ChangeLevel(s, pos, false);
|
||||
G_ChangeLevel(s, pos, 0);
|
||||
break;
|
||||
|
||||
case DEM_SUICIDE:
|
||||
|
@ -2348,22 +2364,25 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
|
||||
case DEM_KILLCLASSCHEAT:
|
||||
{
|
||||
AActor *actor;
|
||||
TThinkerIterator<AActor> iterator;
|
||||
|
||||
char *classname = ReadString (stream);
|
||||
int killcount = 0;
|
||||
PClassActor *cls = PClass::FindActor(classname);
|
||||
|
||||
while ( (actor = iterator.Next ()) )
|
||||
if (cls != NULL)
|
||||
{
|
||||
if (!stricmp (actor->GetClass ()->TypeName.GetChars (), classname))
|
||||
killcount = KillAll(cls);
|
||||
const PClass *cls_rep = cls->GetReplacement();
|
||||
if (cls != cls_rep)
|
||||
{
|
||||
if (!(actor->flags2 & MF2_DORMANT) && (actor->flags3 & MF3_ISMONSTER))
|
||||
killcount += actor->Massacre ();
|
||||
killcount += KillAll(cls_rep);
|
||||
}
|
||||
Printf ("Killed %d monsters of type %s.\n",killcount, classname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("%s is not an actor class.\n", classname);
|
||||
}
|
||||
|
||||
Printf ("Killed %d monsters of type %s.\n",killcount, classname);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -772,10 +772,6 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
// Rebuild translation in case the new skin uses a different range
|
||||
// than the old one.
|
||||
R_BuildPlayerTranslation (i);
|
||||
if (StatusBar != NULL && i == StatusBar->GetPlayer())
|
||||
{
|
||||
StatusBar->SetFace (&skins[info->skin]);
|
||||
}
|
||||
break;
|
||||
|
||||
case INFO_Gender:
|
||||
|
|
|
@ -320,7 +320,7 @@ public:
|
|||
short fixedlightlevel;
|
||||
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
|
||||
int morphTics; // player is a chicken/pig if > 0
|
||||
BYTE MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
PClassPlayerPawn *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
int MorphStyle; // which effects to apply for this player instance when morphed
|
||||
PClassActor *MorphExitFlash; // flash to apply when demorphing (cache of value given to P_MorphPlayer)
|
||||
TObjPtr<AWeapon> PremorphWeapon; // ready weapon before morphing
|
||||
|
|
|
@ -403,7 +403,7 @@ void FDecalLib::ReadDecals(FScanner &sc)
|
|||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetStringName(NULL);
|
||||
sc.ScriptError("Unknown decaldef keyword '%s'", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,40 @@ ClassReg DObject::RegistrationInfo =
|
|||
};
|
||||
_DECLARE_TI(DObject)
|
||||
|
||||
CCMD (dumpactors)
|
||||
{
|
||||
const char *const filters[32] =
|
||||
{
|
||||
"0:All", "1:Doom", "2:Heretic", "3:DoomHeretic", "4:Hexen", "5:DoomHexen", "6:Raven", "7:IdRaven",
|
||||
"8:Strife", "9:DoomStrife", "10:HereticStrife", "11:DoomHereticStrife", "12:HexenStrife",
|
||||
"13:DoomHexenStrife", "14:RavenStrife", "15:NotChex", "16:Chex", "17:DoomChex", "18:HereticChex",
|
||||
"19:DoomHereticChex", "20:HexenChex", "21:DoomHexenChex", "22:RavenChex", "23:NotStrife", "24:StrifeChex",
|
||||
"25:DoomStrifeChex", "26:HereticStrifeChex", "27:NotHexen", "28:HexenStrifeChex", "29:NotHeretic",
|
||||
"30:NotDoom", "31:All",
|
||||
};
|
||||
Printf("%i object class types total\nActor\tEd Num\tSpawnID\tFilter\tSource\n", PClass::AllClasses.Size());
|
||||
for (unsigned int i = 0; i < PClass::AllClasses.Size(); i++)
|
||||
{
|
||||
PClass *cls = PClass::AllClasses[i];
|
||||
PClassActor *acls = dyn_cast<PClassActor>(cls);
|
||||
if (acls != NULL)
|
||||
{
|
||||
Printf("%s\t%i\t%i\t%s\t%s\n",
|
||||
acls->TypeName.GetChars(), acls->DoomEdNum,
|
||||
acls->SpawnID, filters[acls->GameFilter & 31],
|
||||
acls->SourceLumpName.GetChars());
|
||||
}
|
||||
else if (cls != NULL)
|
||||
{
|
||||
Printf("%s\tn/a\tn/a\tn/a\tEngine (not an actor type)\n", cls->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Type %i is not an object class\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (dumpclasses)
|
||||
{
|
||||
// This is by no means speed-optimized. But it's an informational console
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "r_interpolate.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_argv.h"
|
||||
#include "po_man.h"
|
||||
#include "autosegs.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
// Some global defines, that configure the game.
|
||||
#include "doomdef.h"
|
||||
#include "m_swap.h"
|
||||
|
||||
//
|
||||
// Map level types.
|
||||
|
@ -138,7 +139,7 @@ enum ELineFlags
|
|||
ML_ADDTRANS = 0x00000400, // additive translucency (can only be set internally)
|
||||
|
||||
// Extended flags
|
||||
ML_MONSTERSCANACTIVATE = 0x00002000, // [RH] Monsters (as well as players) can active the line
|
||||
ML_MONSTERSCANACTIVATE = 0x00002000, // [RH] Monsters (as well as players) can activate the line
|
||||
ML_BLOCK_PLAYERS = 0x00004000,
|
||||
ML_BLOCKEVERYTHING = 0x00008000, // [RH] Line blocks everything
|
||||
ML_ZONEBOUNDARY = 0x00010000,
|
||||
|
@ -168,8 +169,9 @@ enum SPAC
|
|||
SPAC_AnyCross = 1<<7, // when anything without the MF2_TELEPORT flag crosses the line
|
||||
SPAC_MUse = 1<<8, // monsters can use
|
||||
SPAC_MPush = 1<<9, // monsters can push
|
||||
SPAC_UseBack = 1<<10, // Can be used from the backside
|
||||
|
||||
SPAC_PlayerActivate = (SPAC_Cross|SPAC_Use|SPAC_Impact|SPAC_Push|SPAC_AnyCross|SPAC_UseThrough),
|
||||
SPAC_PlayerActivate = (SPAC_Cross|SPAC_Use|SPAC_Impact|SPAC_Push|SPAC_AnyCross|SPAC_UseThrough|SPAC_UseBack),
|
||||
};
|
||||
|
||||
enum EMapLineFlags // These are flags that use different values internally
|
||||
|
@ -220,6 +222,13 @@ struct mapsubsector_t
|
|||
WORD firstseg; // index of first one, segs are stored sequentially
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct mapsubsector4_t
|
||||
{
|
||||
WORD numsegs;
|
||||
DWORD firstseg; // index of first one, segs are stored sequentially
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
// LineSeg, generated by splitting LineDefs
|
||||
// using partition lines selected by BSP builder.
|
||||
|
@ -231,6 +240,22 @@ struct mapseg_t
|
|||
WORD linedef;
|
||||
SWORD side;
|
||||
SWORD offset;
|
||||
|
||||
int V1() { return LittleShort(v1); }
|
||||
int V2() { return LittleShort(v2); }
|
||||
};
|
||||
|
||||
struct mapseg4_t
|
||||
{
|
||||
SDWORD v1;
|
||||
SDWORD v2;
|
||||
SWORD angle;
|
||||
WORD linedef;
|
||||
SWORD side;
|
||||
SWORD offset;
|
||||
|
||||
int V1() { return LittleLong(v1); }
|
||||
int V2() { return LittleLong(v2); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -238,18 +263,40 @@ struct mapseg_t
|
|||
// BSP node structure.
|
||||
|
||||
// Indicate a leaf.
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
|
||||
struct mapnode_t
|
||||
{
|
||||
enum
|
||||
{
|
||||
NF_SUBSECTOR = 0x8000,
|
||||
NF_LUMPOFFSET = 0
|
||||
};
|
||||
SWORD x,y,dx,dy; // partition line
|
||||
SWORD bbox[2][4]; // bounding box for each child
|
||||
// If NF_SUBSECTOR is or'ed in, it's a subsector,
|
||||
// else it's a node of another subtree.
|
||||
WORD children[2];
|
||||
|
||||
DWORD Child(int num) { return LittleShort(children[num]); }
|
||||
};
|
||||
|
||||
|
||||
struct mapnode4_t
|
||||
{
|
||||
enum
|
||||
{
|
||||
NF_SUBSECTOR = 0x80000000,
|
||||
NF_LUMPOFFSET = 8
|
||||
};
|
||||
SWORD x,y,dx,dy; // partition line
|
||||
SWORD bbox[2][4]; // bounding box for each child
|
||||
// If NF_SUBSECTOR is or'ed in, it's a subsector,
|
||||
// else it's a node of another subtree.
|
||||
DWORD children[2];
|
||||
|
||||
DWORD Child(int num) { return LittleLong(children[num]); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Thing definition, position, orientation and type,
|
||||
|
@ -293,6 +340,7 @@ struct FMapThing
|
|||
DWORD flags;
|
||||
int special;
|
||||
int args[5];
|
||||
int Conversation;
|
||||
|
||||
void Serialize (FArchive &);
|
||||
};
|
||||
|
|
|
@ -290,8 +290,10 @@ enum
|
|||
DF2_NO_AUTOMAP_ALLIES = 1 << 19, // Allies can been seen on the automap.
|
||||
DF2_DISALLOW_SPYING = 1 << 20, // You can spy on your allies.
|
||||
DF2_CHASECAM = 1 << 21, // Players can use the chasecam cheat.
|
||||
DF2_NOSUICIDE = 1 << 22, // Players are allowed to suicide.
|
||||
DF2_NOSUICIDE = 1 << 22, // Players are not allowed to suicide.
|
||||
DF2_NOAUTOAIM = 1 << 23, // Players cannot use autoaim.
|
||||
DF2_DONTCHECKAMMO = 1 << 24, // Don't Check ammo when switching weapons.
|
||||
DF2_KILLBOSSMONST = 1 << 25, // Kills all monsters spawned by a boss cube when the boss dies
|
||||
};
|
||||
|
||||
// [RH] Compatibility flags.
|
||||
|
@ -325,6 +327,9 @@ enum
|
|||
COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs.
|
||||
COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines.
|
||||
COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance
|
||||
COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code.
|
||||
COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom
|
||||
COMPATF_POLYOBJ = 1 << 30, // Draw polyobjects the old fashioned way
|
||||
};
|
||||
|
||||
// Emulate old bugs for select maps. These are not exposed by a cvar
|
||||
|
@ -333,8 +338,7 @@ enum
|
|||
{
|
||||
BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow
|
||||
BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps
|
||||
BCOMPATF_SPECHITOVERFLOW = 1 << 2, // Emulate spechit overflow (e.g. Strain MAP07)
|
||||
BCOMPATF_VILEGHOSTS = 1 << 3, // Monsters' radius and height aren't restored properly when resurrected.
|
||||
BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected.
|
||||
};
|
||||
|
||||
// phares 3/20/98:
|
||||
|
|
|
@ -44,12 +44,6 @@
|
|||
|
||||
// Since this file is included by everything, it seems an appropriate place
|
||||
// to check the NOASM/USEASM macros.
|
||||
#if defined(__APPLE__)
|
||||
// The assembly code needs to be tweaked for Mach-O before enabled on Macs.
|
||||
#ifndef NOASM
|
||||
#define NOASM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// There are three assembly-related macros:
|
||||
//
|
||||
|
|
|
@ -723,7 +723,7 @@ bool F_CastResponder (event_t* ev)
|
|||
if (ev->type != EV_KeyDown)
|
||||
return false;
|
||||
|
||||
const char *cmd = C_GetBinding (ev->data1);
|
||||
const char *cmd = Bindings.GetBind (ev->data1);
|
||||
|
||||
if (cmd != NULL && !stricmp (cmd, "toggleconsole"))
|
||||
return false;
|
||||
|
@ -1226,7 +1226,7 @@ void F_Drawer (void)
|
|||
FTextureID picnum = TexMan.CheckForTexture (FinaleFlat, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
|
||||
if (picnum.isValid())
|
||||
{
|
||||
screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan(picnum));
|
||||
screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan[picnum]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1322,15 +1322,15 @@ void F_Drawer (void)
|
|||
if (multiplayer)
|
||||
{
|
||||
screen->DrawTexture (TexMan["CHESSALL"], 20, 0,
|
||||
DTA_VirtualWidth, w,
|
||||
DTA_VirtualHeight, h, TAG_DONE);
|
||||
DTA_VirtualWidthF, w,
|
||||
DTA_VirtualHeightF, h, TAG_DONE);
|
||||
}
|
||||
else if (players[consoleplayer].CurrentPlayerClass > 0)
|
||||
{
|
||||
picname = players[consoleplayer].CurrentPlayerClass == 1 ? "CHESSC" : "CHESSM";
|
||||
screen->DrawTexture (TexMan[picname], 60, 0,
|
||||
DTA_VirtualWidth, w,
|
||||
DTA_VirtualHeight, h, TAG_DONE);
|
||||
DTA_VirtualWidthF, w,
|
||||
DTA_VirtualHeightF, h, TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,6 +282,10 @@ template<> inline FArchive &operator<< <FFont> (FArchive &arc, FFont* &font)
|
|||
return SerializeFFontPtr (arc, font);
|
||||
}
|
||||
|
||||
struct FStrifeDialogueNode;
|
||||
template<> FArchive &operator<< (FArchive &arc, FStrifeDialogueNode *&node);
|
||||
|
||||
|
||||
|
||||
template<class T,class TT>
|
||||
inline FArchive &operator<< (FArchive &arc, TArray<T,TT> &self)
|
||||
|
|
|
@ -132,6 +132,8 @@ long FileReader::Seek (long offset, int origin)
|
|||
|
||||
long FileReader::Read (void *buffer, long len)
|
||||
{
|
||||
assert(len >= 0);
|
||||
if (len <= 0) return 0;
|
||||
if (FilePos + len > StartPos + Length)
|
||||
{
|
||||
len = Length - FilePos + StartPos;
|
||||
|
|
59
src/files.h
59
src/files.h
|
@ -8,7 +8,56 @@
|
|||
#include "doomtype.h"
|
||||
#include "m_swap.h"
|
||||
|
||||
class FileReader
|
||||
class FileReaderBase
|
||||
{
|
||||
public:
|
||||
virtual ~FileReaderBase() {}
|
||||
virtual long Read (void *buffer, long len) = 0;
|
||||
|
||||
FileReaderBase &operator>> (BYTE &v)
|
||||
{
|
||||
Read (&v, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileReaderBase &operator>> (SBYTE &v)
|
||||
{
|
||||
Read (&v, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileReaderBase &operator>> (WORD &v)
|
||||
{
|
||||
Read (&v, 2);
|
||||
v = LittleShort(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileReaderBase &operator>> (SWORD &v)
|
||||
{
|
||||
Read (&v, 2);
|
||||
v = LittleShort(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileReaderBase &operator>> (DWORD &v)
|
||||
{
|
||||
Read (&v, 4);
|
||||
v = LittleLong(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileReaderBase &operator>> (fixed_t &v)
|
||||
{
|
||||
Read (&v, 4);
|
||||
v = LittleLong(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class FileReader : public FileReaderBase
|
||||
{
|
||||
public:
|
||||
FileReader ();
|
||||
|
@ -82,13 +131,13 @@ protected:
|
|||
};
|
||||
|
||||
// Wraps around a FileReader to decompress a zlib stream
|
||||
class FileReaderZ
|
||||
class FileReaderZ : public FileReaderBase
|
||||
{
|
||||
public:
|
||||
FileReaderZ (FileReader &file, bool zip=false);
|
||||
~FileReaderZ ();
|
||||
|
||||
long Read (void *buffer, long len);
|
||||
virtual long Read (void *buffer, long len);
|
||||
|
||||
FileReaderZ &operator>> (BYTE &v)
|
||||
{
|
||||
|
@ -144,7 +193,7 @@ private:
|
|||
};
|
||||
|
||||
// Wraps around a FileReader to decompress a bzip2 stream
|
||||
class FileReaderBZ2
|
||||
class FileReaderBZ2 : public FileReaderBase
|
||||
{
|
||||
public:
|
||||
FileReaderBZ2 (FileReader &file);
|
||||
|
@ -206,7 +255,7 @@ private:
|
|||
};
|
||||
|
||||
// Wraps around a FileReader to decompress a lzma stream
|
||||
class FileReaderLZMA
|
||||
class FileReaderLZMA : public FileReaderBase
|
||||
{
|
||||
public:
|
||||
FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip);
|
||||
|
|
|
@ -85,6 +85,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
|
|||
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
|
||||
return 0;
|
||||
|
||||
// New dmflag: Kill all boss spawned monsters before ending the level.
|
||||
if (dmflags2 & DF2_KILLBOSSMONST)
|
||||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
while ((mo = it.Next()))
|
||||
{
|
||||
if (mo->flags4 & MF4_BOSSSPAWNED)
|
||||
{
|
||||
P_DamageMobj(mo, self, self, mo->health, NAME_None,
|
||||
DMG_NO_ARMOR|DMG_FORCED|DMG_THRUSTLESS|DMG_NO_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G_ExitLevel (0, false);
|
||||
return 0;
|
||||
}
|
||||
|
@ -261,6 +276,7 @@ static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound)
|
|||
// telefrag anything in this spot
|
||||
P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);
|
||||
}
|
||||
newmobj->flags4 |= MF4_BOSSSPAWNED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
|||
|
||||
angle += pr_punch.Random2() << 18;
|
||||
pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true);
|
||||
|
||||
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget);
|
||||
|
||||
// turn to face target
|
||||
if (linetarget)
|
||||
|
@ -105,15 +106,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
|
|||
//
|
||||
// A_Saw
|
||||
//
|
||||
enum SAW_Flags
|
||||
{
|
||||
SF_NORANDOM = 1,
|
||||
SF_RANDOMLIGHTMISS = 2,
|
||||
SF_RANDOMLIGHTHIT = 4,
|
||||
SF_NOUSEAMMOMISS = 8,
|
||||
SF_NOUSEAMMO = 16,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_SOUND_OPT (fullsound) { fullsound = "weapons/sawfull"; }
|
||||
PARAM_SOUND_OPT (fullsound) { fullsound = "weapons/sawfull"; }
|
||||
PARAM_SOUND_OPT (hitsound) { hitsound = "weapons/sawhit"; }
|
||||
PARAM_INT_OPT (damage) { damage = 2; }
|
||||
PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; }
|
||||
PARAM_INT_OPT (flags) { flags = 0; }
|
||||
PARAM_FIXED_OPT (range) { range = 0; }
|
||||
PARAM_ANGLE_OPT (spread_xy) { spread_xy = angle_t(2.8125 * (ANGLE_90 / 90.0)); }
|
||||
PARAM_ANGLE_OPT (spread_z) { spread_z = 0; }
|
||||
PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; }
|
||||
|
||||
angle_t angle;
|
||||
angle_t angle;
|
||||
angle_t slope;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
|
||||
|
@ -122,13 +138,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pufftype == NULL)
|
||||
{
|
||||
pufftype = PClass::FindActor(NAME_BulletPuff);
|
||||
|
@ -137,21 +146,61 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
{
|
||||
damage = 2;
|
||||
}
|
||||
|
||||
damage *= (pr_saw()%10 + 1);
|
||||
angle = self->angle;
|
||||
angle += pr_saw.Random2() << 18;
|
||||
|
||||
// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
|
||||
P_LineAttack (self, angle, MELEERANGE+1,
|
||||
P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
|
||||
if (!(flags & SF_NORANDOM))
|
||||
{
|
||||
damage *= (pr_saw()%10+1);
|
||||
}
|
||||
if (range == 0)
|
||||
{ // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
|
||||
range = MELEERANGE+1;
|
||||
}
|
||||
|
||||
angle = self->angle + (pr_saw.Random2() * (spread_xy / 255));
|
||||
slope = P_AimLineAttack (self, angle, range, &linetarget) + (pr_saw.Random2() * (spread_z / 255));
|
||||
|
||||
P_LineAttack (self, angle, range,
|
||||
slope, damage,
|
||||
NAME_None, pufftype);
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!linetarget && (flags & SF_NOUSEAMMOMISS)))
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!linetarget)
|
||||
{
|
||||
if ((flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64))
|
||||
{
|
||||
player->extralight = !player->extralight;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & SF_RANDOMLIGHTHIT)
|
||||
{
|
||||
int randVal = pr_saw();
|
||||
if (randVal < 64)
|
||||
{
|
||||
player->extralight = 0;
|
||||
}
|
||||
else if (randVal < 160)
|
||||
{
|
||||
player->extralight = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->extralight = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (lifesteal)
|
||||
{
|
||||
P_GiveBody (self, (damage * lifesteal) >> FRACBITS);
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
|
||||
|
||||
// turn to face target
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT(doortag);
|
||||
PARAM_INT_OPT(doortag) { doortag = 666; }
|
||||
|
||||
CALL_ACTION(A_NoBlocking, self);
|
||||
A_Unblock(self, false);
|
||||
|
||||
// scan the remaining thinkers to see if all Keens are dead
|
||||
AActor *other;
|
||||
|
|
|
@ -179,7 +179,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
|
|||
self->flags &= ~MF_FRIENDLY;
|
||||
}
|
||||
PClassActor *spawntype = GetSpawnType(numparam > NAP ? ¶m[NAP] : NULL);
|
||||
CALL_ACTION(A_NoBlocking, self);
|
||||
A_Unblock(self, true);
|
||||
A_PainShootSkull (self, self->angle + ANG90, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG180, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG270, spawntype);
|
||||
|
|
|
@ -283,7 +283,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
|
|||
|
||||
P_LineAttack (self, angle, MELEERANGE+1,
|
||||
P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
|
||||
NAME_Melee, pufftype);
|
||||
NAME_Melee, pufftype, false, &linetarget);
|
||||
|
||||
if (!linetarget)
|
||||
{
|
||||
|
@ -338,7 +338,7 @@ static void MarinePunch(AActor *self, int damagemul)
|
|||
A_FaceTarget (self);
|
||||
angle = self->angle + (pr_m_punch.Random2() << 18);
|
||||
pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true);
|
||||
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget);
|
||||
|
||||
// turn to face target
|
||||
if (linetarget)
|
||||
|
|
|
@ -116,13 +116,13 @@ EXTERN_CVAR (Float, con_midtime);
|
|||
//
|
||||
// CVAR displaynametags
|
||||
//
|
||||
// Selects whether to display name tags or not when changing weapons
|
||||
// Selects whether to display name tags or not when changing weapons/items
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CUSTOM_CVAR (Bool, displaynametags, 0, CVAR_ARCHIVE)
|
||||
CUSTOM_CVAR (Int, displaynametags, 0, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self != 0 && self != 1)
|
||||
if (self < 0 || self > 3)
|
||||
{
|
||||
self = 0;
|
||||
}
|
||||
|
@ -288,7 +288,8 @@ CCMD (slot)
|
|||
|
||||
if (slot < NUM_WEAPON_SLOTS)
|
||||
{
|
||||
SendItemUse = players[consoleplayer].weapons.Slots[slot].PickWeapon (&players[consoleplayer]);
|
||||
SendItemUse = players[consoleplayer].weapons.Slots[slot].PickWeapon (&players[consoleplayer],
|
||||
!(dmflags2 & DF2_DONTCHECKAMMO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,11 +322,23 @@ CCMD (turn180)
|
|||
CCMD (weapnext)
|
||||
{
|
||||
SendItemUse = players[consoleplayer].weapons.PickNextWeapon (&players[consoleplayer]);
|
||||
// [BC] Option to display the name of the weapon being cycled to.
|
||||
if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
|
||||
{
|
||||
StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, SendItemUse->GetTag(),
|
||||
1.5f, 0.90f, 0, 0, CR_GOLD, 2.f, 0.35f), MAKE_ID( 'W', 'E', 'P', 'N' ));
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (weapprev)
|
||||
{
|
||||
SendItemUse = players[consoleplayer].weapons.PickPrevWeapon (&players[consoleplayer]);
|
||||
// [BC] Option to display the name of the weapon being cycled to.
|
||||
if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
|
||||
{
|
||||
StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, SendItemUse->GetTag(),
|
||||
1.5f, 0.90f, 0, 0, CR_GOLD, 2.f, 0.35f), MAKE_ID( 'W', 'E', 'P', 'N' ));
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (invnext)
|
||||
|
@ -353,10 +366,9 @@ CCMD (invnext)
|
|||
who->InvSel = who->Inventory;
|
||||
}
|
||||
}
|
||||
if (displaynametags && StatusBar && SmallFont
|
||||
&& gamestate == GS_LEVEL && level.time > con_midtime && who->InvSel)
|
||||
StatusBar->AttachMessage (new DHUDMessage (SmallFont, who->InvSel->GetTag(),
|
||||
2.5f, 0.375f, 0, 0, CR_YELLOW, con_midtime), MAKE_ID('S','I','N','V'));
|
||||
if ((displaynametags & 1) && StatusBar && SmallFont && who->InvSel)
|
||||
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, who->InvSel->GetTag(),
|
||||
1.5f, 0.80f, 0, 0, CR_GOLD, 2.f, 0.35f), MAKE_ID('S','I','N','V'));
|
||||
}
|
||||
who->player->inventorytics = 5*TICRATE;
|
||||
}
|
||||
|
@ -384,10 +396,9 @@ CCMD (invprev)
|
|||
}
|
||||
who->InvSel = item;
|
||||
}
|
||||
if (displaynametags && StatusBar && SmallFont
|
||||
&& gamestate == GS_LEVEL && level.time > con_midtime && who->InvSel)
|
||||
StatusBar->AttachMessage (new DHUDMessage (SmallFont, who->InvSel->GetTag(),
|
||||
2.5f, 0.375f, 0, 0, CR_YELLOW, con_midtime), MAKE_ID('S','I','N','V'));
|
||||
if ((displaynametags & 1) && StatusBar && SmallFont && who->InvSel)
|
||||
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, who->InvSel->GetTag(),
|
||||
1.5f, 0.80f, 0, 0, CR_GOLD, 2.f, 0.35f), MAKE_ID('S','I','N','V'));
|
||||
}
|
||||
who->player->inventorytics = 5*TICRATE;
|
||||
}
|
||||
|
@ -871,7 +882,7 @@ bool G_Responder (event_t *ev)
|
|||
if (gameaction == ga_nothing &&
|
||||
(demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL))
|
||||
{
|
||||
const char *cmd = C_GetBinding (ev->data1);
|
||||
const char *cmd = Bindings.GetBind (ev->data1);
|
||||
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
|
@ -894,11 +905,11 @@ bool G_Responder (event_t *ev)
|
|||
}
|
||||
else
|
||||
{
|
||||
return C_DoKey (ev);
|
||||
return C_DoKey (ev, &Bindings, &DoubleBindings);
|
||||
}
|
||||
}
|
||||
if (cmd && cmd[0] == '+')
|
||||
return C_DoKey (ev);
|
||||
return C_DoKey (ev, &Bindings, &DoubleBindings);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -910,7 +921,7 @@ bool G_Responder (event_t *ev)
|
|||
{
|
||||
if (ST_Responder (ev))
|
||||
return true; // status window ate it
|
||||
if (!viewactive && AM_Responder (ev))
|
||||
if (!viewactive && AM_Responder (ev, false))
|
||||
return true; // automap ate it
|
||||
}
|
||||
else if (gamestate == GS_FINALE)
|
||||
|
@ -922,12 +933,12 @@ bool G_Responder (event_t *ev)
|
|||
switch (ev->type)
|
||||
{
|
||||
case EV_KeyDown:
|
||||
if (C_DoKey (ev))
|
||||
if (C_DoKey (ev, &Bindings, &DoubleBindings))
|
||||
return true;
|
||||
break;
|
||||
|
||||
case EV_KeyUp:
|
||||
C_DoKey (ev);
|
||||
C_DoKey (ev, &Bindings, &DoubleBindings);
|
||||
break;
|
||||
|
||||
// [RH] mouse buttons are sent as key up/down events
|
||||
|
@ -941,7 +952,7 @@ bool G_Responder (event_t *ev)
|
|||
// the events *last* so that any bound keys get precedence.
|
||||
|
||||
if (gamestate == GS_LEVEL && viewactive)
|
||||
return AM_Responder (ev);
|
||||
return AM_Responder (ev, true);
|
||||
|
||||
return (ev->type == EV_KeyDown ||
|
||||
ev->type == EV_Mouse);
|
||||
|
@ -1165,7 +1176,9 @@ void G_Ticker ()
|
|||
// G_PlayerFinishLevel
|
||||
// Called when a player completes a level.
|
||||
//
|
||||
void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory)
|
||||
// flags is checked for RESETINVENTORY and RESETHEALTH only.
|
||||
|
||||
void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
|
||||
{
|
||||
AInventory *item, *next;
|
||||
player_t *p;
|
||||
|
@ -1237,8 +1250,14 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory
|
|||
P_UndoPlayerMorph (p, p, 0, true);
|
||||
}
|
||||
|
||||
// Resets player health to default
|
||||
if (flags & CHANGELEVEL_RESETHEALTH)
|
||||
{
|
||||
p->health = p->mo->health = p->mo->SpawnHealth();
|
||||
}
|
||||
|
||||
// Clears the entire inventory and gives back the defaults for starting a game
|
||||
if (resetinventory)
|
||||
if (flags & CHANGELEVEL_RESETINVENTORY)
|
||||
{
|
||||
AInventory *inv = p->mo->Inventory;
|
||||
|
||||
|
@ -2044,11 +2063,11 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
|
|||
M_AppendPNGChunk (stdfile, MAKE_ID('s','n','X','t'), &next, 1);
|
||||
}
|
||||
|
||||
M_NotifyNewSave (filename.GetChars(), description, okForQuicksave);
|
||||
|
||||
M_FinishPNG (stdfile);
|
||||
fclose (stdfile);
|
||||
|
||||
M_NotifyNewSave (filename.GetChars(), description, okForQuicksave);
|
||||
|
||||
// Check whether the file is ok.
|
||||
bool success = false;
|
||||
stdfile = fopen (filename.GetChars(), "rb");
|
||||
|
|
|
@ -71,7 +71,7 @@ enum EFinishLevelType
|
|||
FINISH_NoHub
|
||||
};
|
||||
|
||||
void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory);
|
||||
void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags);
|
||||
|
||||
void G_DoReborn (int playernum, bool freshbot);
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|||
damage = 1 + (pr_beakatkpl1()&3);
|
||||
angle = player->mo->angle;
|
||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
player->mo->angle = R_PointToAngle2 (player->mo->x,
|
||||
|
@ -222,7 +222,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
|||
damage = pr_beakatkpl2.HitDice (4);
|
||||
angle = player->mo->angle;
|
||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
player->mo->angle = R_PointToAngle2 (player->mo->x,
|
||||
|
|
|
@ -151,7 +151,7 @@ void P_DSparilTeleport (AActor *actor)
|
|||
DSpotState *state = DSpotState::GetSpotState();
|
||||
if (state == NULL) return;
|
||||
|
||||
spot = state->GetSpotWithMinDistance(PClass::FindClass("BossSpot"), actor->x, actor->y, 128*FRACUNIT);
|
||||
spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->x, actor->y, 128*FRACUNIT, 0);
|
||||
if (spot == NULL) return;
|
||||
|
||||
prevX = actor->x;
|
||||
|
|
|
@ -89,7 +89,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
|
|||
angle = self->angle;
|
||||
angle += pr_sap.Random2() << 18;
|
||||
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true);
|
||||
P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
//S_StartSound(player->mo, sfx_stfhit);
|
||||
|
@ -291,7 +291,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
pufftype = PClass::FindActor("GauntletPuff1");
|
||||
}
|
||||
slope = P_AimLineAttack (self, angle, dist, &linetarget);
|
||||
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype);
|
||||
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget);
|
||||
if (!linetarget)
|
||||
{
|
||||
if (pr_gatk() > 64)
|
||||
|
|
|
@ -1,795 +0,0 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_font.h"
|
||||
#include "sbar.h"
|
||||
#include "r_defs.h"
|
||||
#include "w_wad.h"
|
||||
#include "m_random.h"
|
||||
#include "d_player.h"
|
||||
#include "st_stuff.h"
|
||||
#include "v_video.h"
|
||||
#include "r_draw.h"
|
||||
#include "templates.h"
|
||||
#include "a_keys.h"
|
||||
#include "r_translate.h"
|
||||
#include "g_level.h"
|
||||
#include "v_palette.h"
|
||||
|
||||
|
||||
static FRandom pr_chainwiggle;
|
||||
|
||||
// This texture is used to shade each end of the health chain
|
||||
class FHereticShader : public FTexture
|
||||
{
|
||||
public:
|
||||
FHereticShader ();
|
||||
|
||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const BYTE *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
private:
|
||||
static const BYTE Pixels[10*16];
|
||||
static const Span DummySpan[2];
|
||||
};
|
||||
|
||||
static FHereticShader ChainShade;
|
||||
|
||||
const FTexture::Span FHereticShader::DummySpan[2] = { { 0, 10 }, { 0, 0 } };
|
||||
const BYTE FHereticShader::Pixels[10*16] =
|
||||
{
|
||||
254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
|
||||
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
|
||||
224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
|
||||
208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
|
||||
192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
|
||||
176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
|
||||
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
|
||||
144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
};
|
||||
|
||||
FHereticShader::FHereticShader ()
|
||||
{
|
||||
Width = 16;
|
||||
Height = 10;
|
||||
WidthBits = 4;
|
||||
HeightBits = 4;
|
||||
WidthMask = 15;
|
||||
}
|
||||
|
||||
void FHereticShader::Unload ()
|
||||
{
|
||||
}
|
||||
|
||||
const BYTE *FHereticShader::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
}
|
||||
return Pixels + 10*(column & 15);
|
||||
}
|
||||
|
||||
const BYTE *FHereticShader::GetPixels ()
|
||||
{
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
||||
class DHereticStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DHereticStatusBar, DBaseStatusBar)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DHereticStatusBar () : DBaseStatusBar (42)
|
||||
{
|
||||
static const char *hereticLumpNames[NUM_HERETICSB_IMAGES] =
|
||||
{
|
||||
"LTFACE", "RTFACE", "BARBACK", "INVBAR", "CHAIN",
|
||||
NULL, "LIFEGEM2", "LTFCTOP", "RTFCTOP", "SELECTBO",
|
||||
"INVGEML1", "INVGEML2", "INVGEMR1", "INVGEMR2", "BLACKSQ",
|
||||
"ARMCLEAR", "CHAINBACK","GOD1", "GOD2", "USEARTIA",
|
||||
"USEARTIB", "USEARTIC", "USEARTID", "YKEYICON", "GKEYICON",
|
||||
"BKEYICON", "ARTIBOX", "PTN1A0", "PTN1B0", "PTN1C0"
|
||||
};
|
||||
static const char *sharedLumpNames[] =
|
||||
{
|
||||
"LAME", "NEGNUM", "IN0", "IN1", "IN2",
|
||||
"IN3", "IN4", "IN5", "IN6", "IN7",
|
||||
"IN8", "IN9", "FONTB13", "FONTB16", "FONTB17",
|
||||
"FONTB18", "FONTB19", "FONTB20", "FONTB21", "FONTB22",
|
||||
"FONTB23", "FONTB24", "FONTB25", "SMALLIN0", "SMALLIN1",
|
||||
"SMALLIN2", "SMALLIN3", "SMALLIN4", "SMALLIN5", "SMALLIN6",
|
||||
"SMALLIN7", "SMALLIN8", "SMALLIN9"
|
||||
};
|
||||
|
||||
if (deathmatch)
|
||||
{
|
||||
hereticLumpNames[5] = "STATBAR";
|
||||
}
|
||||
else
|
||||
{
|
||||
hereticLumpNames[5] = "LIFEBAR";
|
||||
}
|
||||
|
||||
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
Images.Init (hereticLumpNames, NUM_HERETICSB_IMAGES);
|
||||
|
||||
oldarti = NULL;
|
||||
oldammo1 = oldammo2 = NULL;
|
||||
oldammocount1 = oldammocount2 = -1;
|
||||
oldartiCount = 0;
|
||||
oldfrags = -9999;
|
||||
oldarmor = -1;
|
||||
oldhealth = -1;
|
||||
oldlife = -1;
|
||||
oldkeys = -1;
|
||||
|
||||
HealthMarker = 0;
|
||||
ChainWiggle = 0;
|
||||
ArtifactFlash = 0;
|
||||
}
|
||||
|
||||
~DHereticStatusBar ()
|
||||
{
|
||||
}
|
||||
|
||||
void Tick ()
|
||||
{
|
||||
int curHealth;
|
||||
|
||||
DBaseStatusBar::Tick ();
|
||||
if (level.time & 1)
|
||||
{
|
||||
ChainWiggle = pr_chainwiggle() & 1;
|
||||
}
|
||||
curHealth = CPlayer->health;
|
||||
if (curHealth < 0)
|
||||
{
|
||||
curHealth = 0;
|
||||
}
|
||||
if (curHealth < HealthMarker)
|
||||
{
|
||||
HealthMarker -= clamp ((HealthMarker - curHealth) >> 2, 1, 8);
|
||||
}
|
||||
else if (curHealth > HealthMarker)
|
||||
{
|
||||
HealthMarker += clamp ((curHealth - HealthMarker) >> 2, 1, 8);
|
||||
}
|
||||
|
||||
if (ArtifactFlash > 0)
|
||||
{
|
||||
if (--ArtifactFlash == 0)
|
||||
{
|
||||
ArtiRefresh = screen->GetPageCount ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
DBaseStatusBar::Draw (state);
|
||||
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
DrawFullScreenStuff ();
|
||||
SB_state = screen->GetPageCount ();
|
||||
}
|
||||
else if (state == HUD_StatusBar)
|
||||
{
|
||||
if (SB_state > 0)
|
||||
{
|
||||
DrawImage (Images[imgBARBACK], 0, 0);
|
||||
if (CPlayer->cheats&CF_GODMODE)
|
||||
{
|
||||
DrawImage (Images[imgGOD1], 16, 9);
|
||||
DrawImage (Images[imgGOD2], 287, 9);
|
||||
}
|
||||
oldhealth = -1;
|
||||
}
|
||||
DrawCommonBar ();
|
||||
if (CPlayer->inventorytics == 0)
|
||||
{
|
||||
if (SB_state < 0)
|
||||
{
|
||||
SB_state = screen->GetPageCount ();
|
||||
}
|
||||
if (SB_state != 0)
|
||||
{
|
||||
// Main interface
|
||||
SB_state--;
|
||||
DrawImage (Images[imgSTATBAR], 34, 2);
|
||||
oldarti = NULL;
|
||||
oldammo1 = oldammo2 = NULL;
|
||||
oldammocount1 = oldammocount2 = -1;
|
||||
oldarmor = -1;
|
||||
oldfrags = -9999; //can't use -1, 'cuz of negative frags
|
||||
oldlife = -1;
|
||||
oldkeys = -1;
|
||||
oldhealth = -1;
|
||||
ArtiRefresh = 0;
|
||||
}
|
||||
DrawMainBar ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SB_state > -1)
|
||||
{
|
||||
SB_state = -screen->GetPageCount () - 1;
|
||||
}
|
||||
if (SB_state < -1)
|
||||
{
|
||||
SB_state++;
|
||||
DrawImage (Images[imgINVBAR], 34, 2);
|
||||
}
|
||||
DrawInventoryBar ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawCommonBar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawCommonBar ()
|
||||
{
|
||||
int chainY;
|
||||
int healthPos;
|
||||
|
||||
DrawImage (Images[imgLTFCTOP], 0, -10);
|
||||
//DrawImage (Images[imgRTFCTOP], 290, -10);
|
||||
screen->DrawTexture (Images[imgRTFCTOP], ST_X+290, ST_Y,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
DTA_TopOffset, Images[imgRTFCTOP]->GetHeight(),
|
||||
TAG_DONE);
|
||||
|
||||
if (oldhealth != HealthMarker)
|
||||
{
|
||||
oldhealth = HealthMarker;
|
||||
HealthRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (HealthRefresh)
|
||||
{
|
||||
HealthRefresh--;
|
||||
healthPos = HealthMarker;
|
||||
if (healthPos < 0)
|
||||
{
|
||||
healthPos = 0;
|
||||
}
|
||||
if (healthPos > 100)
|
||||
{
|
||||
healthPos = 100;
|
||||
}
|
||||
healthPos = (healthPos * 256) / 100;
|
||||
chainY = (HealthMarker == (CPlayer->health > 0 ? CPlayer->health : 0)) ? 33 : 33 + ChainWiggle;
|
||||
DrawImage (Images[imgCHAINBACK], 0, 32);
|
||||
DrawImage (Images[imgCHAIN], 2+(healthPos%17), chainY);
|
||||
DrawImage (Images[imgLIFEGEM], 17+healthPos, chainY, multiplayer ?
|
||||
translationtables[TRANSLATION_PlayersExtra][int(CPlayer - players)] : NULL);
|
||||
DrawImage (Images[imgLTFACE], 0, 32);
|
||||
DrawImage (Images[imgRTFACE], 276, 32);
|
||||
screen->DrawTexture (&ChainShade, ST_X+19, ST_Y+32,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
DTA_AlphaChannel, true,
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
screen->DrawTexture (&ChainShade, ST_X+277, ST_Y+32,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
DTA_AlphaChannel, true,
|
||||
DTA_FillColor, 0,
|
||||
DTA_FlipX, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawMainBar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawMainBar ()
|
||||
{
|
||||
AInventory *item;
|
||||
AAmmo *ammo1, *ammo2;
|
||||
int ammocount1, ammocount2;
|
||||
int temp;
|
||||
int playerkeys;
|
||||
|
||||
// Ready artifact
|
||||
if (ArtifactFlash)
|
||||
{
|
||||
DrawImage (Images[imgBLACKSQ], 180, 3);
|
||||
DrawImage (Images[imgUSEARTIA + ArtifactFlash], 182, 3);
|
||||
oldarti = NULL; // so that the correct artifact fills in after the flash
|
||||
}
|
||||
else if (oldarti != CPlayer->mo->InvSel
|
||||
|| (oldarti != NULL && oldartiCount != oldarti->Amount))
|
||||
{
|
||||
oldarti = CPlayer->mo->InvSel;
|
||||
GC::WriteBarrier(this, oldarti);
|
||||
oldartiCount = oldarti != NULL ? oldarti->Amount : 0;
|
||||
ArtiRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (ArtiRefresh)
|
||||
{
|
||||
ArtiRefresh--;
|
||||
DrawImage (Images[imgBLACKSQ], 180, 3);
|
||||
if (oldarti != NULL)
|
||||
{
|
||||
DrawDimImage (TexMan(oldarti->Icon), 179, 2, oldarti->Amount <= 0);
|
||||
if (oldartiCount != 1)
|
||||
{
|
||||
DrSmallNumber (oldartiCount, 197, 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Frags
|
||||
if (deathmatch)
|
||||
{
|
||||
temp = CPlayer->fragcount;
|
||||
if (temp != oldfrags)
|
||||
{
|
||||
oldfrags = temp;
|
||||
FragHealthRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (FragHealthRefresh)
|
||||
{
|
||||
FragHealthRefresh--;
|
||||
DrawImage (Images[imgARMCLEAR], 57, 13);
|
||||
DrINumber (temp, 61, 12);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = MAX(0, HealthMarker);
|
||||
if (oldlife != temp)
|
||||
{
|
||||
oldlife = temp;
|
||||
FragHealthRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (FragHealthRefresh)
|
||||
{
|
||||
FragHealthRefresh--;
|
||||
DrawImage (Images[imgARMCLEAR], 57, 13);
|
||||
DrINumber (temp, 61, 12);
|
||||
}
|
||||
}
|
||||
|
||||
// Keys
|
||||
playerkeys = 0;
|
||||
|
||||
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
if (item->IsKindOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
int keynum = static_cast<AKey*>(item)->KeyNumber;
|
||||
if (keynum >= 1 && keynum <= 3)
|
||||
{
|
||||
playerkeys |= 1 << (keynum-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldkeys != playerkeys)
|
||||
{
|
||||
oldkeys = playerkeys;
|
||||
KeysRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (KeysRefresh)
|
||||
{
|
||||
KeysRefresh--;
|
||||
// [RH] Erase the key images so the player can drop keys
|
||||
// and see the status update.
|
||||
screen->DrawTexture (Images[imgSTATBAR], ST_X+34, ST_Y+2,
|
||||
DTA_WindowLeft, 119,
|
||||
DTA_WindowRight, 129,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
TAG_DONE);
|
||||
if (playerkeys & 4)
|
||||
{
|
||||
DrawImage (Images[imgYKEYICON], 153, 6);
|
||||
}
|
||||
if (playerkeys & 1)
|
||||
{
|
||||
DrawImage (Images[imgGKEYICON], 153, 14);
|
||||
}
|
||||
if (playerkeys & 2)
|
||||
{
|
||||
DrawImage (Images[imgBKEYICON], 153, 22);
|
||||
}
|
||||
}
|
||||
|
||||
// Ammo
|
||||
GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
|
||||
if (ammo1 == ammo2)
|
||||
{
|
||||
// Don't show the same ammo twice.
|
||||
ammo2 = NULL;
|
||||
}
|
||||
if (oldammo1 != ammo1 || oldammo2 != ammo2 ||
|
||||
oldammocount1 != ammocount1 || oldammocount2 != ammocount2)
|
||||
{
|
||||
oldammo1 = ammo1;
|
||||
oldammo2 = ammo2;
|
||||
oldammocount1 = ammocount1;
|
||||
oldammocount2 = ammocount2;
|
||||
GC::WriteBarrier(this, ammo1);
|
||||
GC::WriteBarrier(this, ammo2);
|
||||
AmmoRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (AmmoRefresh)
|
||||
{
|
||||
AmmoRefresh--;
|
||||
DrawImage (Images[imgBLACKSQ], 108, 3);
|
||||
if (ammo2 != NULL)
|
||||
{ // Draw both ammos
|
||||
screen->DrawTexture (TexMan[ammo1->Icon], 115+ST_X, 11+ST_Y,
|
||||
DTA_CenterOffset, true,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
TAG_DONE);
|
||||
DrSmallNumber (ammo1->Amount, 124, 7);
|
||||
screen->DrawTexture (TexMan[ammo2->Icon], 115+ST_X, 22+ST_Y,
|
||||
DTA_CenterOffset, true,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
TAG_DONE);
|
||||
DrSmallNumber (ammo2->Amount, 124, 19);
|
||||
}
|
||||
else if (ammo1 != NULL)
|
||||
{ // Draw just one ammo
|
||||
DrINumber (ammo1->Amount, 109, 4);
|
||||
screen->DrawTexture (TexMan[ammo1->Icon], 123+ST_X, 22+ST_Y,
|
||||
DTA_CenterOffset, true,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Armor
|
||||
AInventory *armor = CPlayer->mo->FindInventory<ABasicArmor>();
|
||||
int armorpoints = armor != NULL ? armor->Amount : 0;
|
||||
if (oldarmor != armorpoints)
|
||||
{
|
||||
oldarmor = armorpoints;
|
||||
ArmorRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (ArmorRefresh)
|
||||
{
|
||||
ArmorRefresh--;
|
||||
DrawImage (Images[imgARMCLEAR], 224, 13);
|
||||
DrINumber (armorpoints, 228, 12);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawInventoryBar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawInventoryBar ()
|
||||
{
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
DrawImage (Images[imgINVBAR], 34, 2);
|
||||
CPlayer->mo->InvFirst = ValidateInvFirst (7);
|
||||
if (CPlayer->mo->InvFirst != NULL)
|
||||
{
|
||||
for (item = CPlayer->mo->InvFirst, i = 0; item != NULL && i < 7; item = item->NextInv(), ++i)
|
||||
{
|
||||
DrawDimImage (TexMan(item->Icon), 50+i*31, 2, item->Amount <= 0);
|
||||
if (item->Amount != 1)
|
||||
{
|
||||
DrSmallNumber (item->Amount, 65+i*31, 24);
|
||||
}
|
||||
if (item == CPlayer->mo->InvSel)
|
||||
{
|
||||
DrawImage (Images[imgSELECTBOX], 50+i*31, 31);
|
||||
}
|
||||
}
|
||||
// Is there something to the left?
|
||||
if (CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
|
||||
{
|
||||
DrawImage (Images[!(gametic & 4) ?
|
||||
imgINVLFGEM1 : imgINVLFGEM2], 38, 1);
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (item != NULL)
|
||||
{
|
||||
DrawImage (Images[!(gametic & 4) ?
|
||||
imgINVRTGEM1 : imgINVRTGEM2], 269, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawFullScreenStuff
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawFullScreenStuff ()
|
||||
{
|
||||
AInventory *item;
|
||||
FTexture *pic;
|
||||
int i;
|
||||
|
||||
// Draw health
|
||||
if (CPlayer->mo->health > 0)
|
||||
{
|
||||
pic = Images[imgPTN1 + gametic/3%3];
|
||||
screen->DrawTexture (pic, 48, -3,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_LeftOffset, pic->GetWidth()/2,
|
||||
DTA_TopOffset, pic->GetHeight(),
|
||||
TAG_DONE);
|
||||
DrBNumberOuter (CPlayer->mo->health, 5, -21);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrBNumberOuter (0, 5, -20);
|
||||
}
|
||||
|
||||
// Draw armor
|
||||
ABasicArmor *armor = CPlayer->mo->FindInventory<ABasicArmor>();
|
||||
if (armor != NULL && armor->Amount != 0)
|
||||
{
|
||||
pic = TexMan(armor->Icon);
|
||||
if (pic != NULL)
|
||||
{
|
||||
screen->DrawTexture (pic, 56, -24,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_LeftOffset, pic->GetWidth()/2,
|
||||
DTA_TopOffset, pic->GetHeight(),
|
||||
TAG_DONE);
|
||||
}
|
||||
DrBNumberOuter (armor->Amount, 5, -43);
|
||||
}
|
||||
|
||||
if (deathmatch)
|
||||
{
|
||||
// Draw frag count
|
||||
DrINumberOuter (CPlayer->fragcount, 45, -16);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw keys
|
||||
int playerkeys = 0;
|
||||
|
||||
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
if (item->IsKindOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
int keynum = static_cast<const AKey*>(item)->KeyNumber;
|
||||
if (keynum >= 1 && keynum <= 3)
|
||||
{
|
||||
playerkeys |= 1 << (keynum-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
i = -7;
|
||||
if (playerkeys & 2)
|
||||
{
|
||||
screen->DrawTexture (Images[imgBKEYICON], 54, i,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
TAG_DONE);
|
||||
i -= 8;
|
||||
}
|
||||
if (playerkeys & 1)
|
||||
{
|
||||
screen->DrawTexture (Images[imgGKEYICON], 54, i,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
TAG_DONE);
|
||||
i -= 8;
|
||||
}
|
||||
if (playerkeys & 4)
|
||||
{
|
||||
screen->DrawTexture (Images[imgYKEYICON], 54, i,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw ammo
|
||||
AAmmo *ammo1, *ammo2;
|
||||
int ammocount1, ammocount2;
|
||||
|
||||
GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
|
||||
if (ammo1 != NULL)
|
||||
{
|
||||
// Draw primary ammo in the bottom-right corner
|
||||
DrINumberOuter (ammo1->Amount, -29, -15);
|
||||
screen->DrawTexture (TexMan(ammo1->Icon), -14, -22,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_CenterBottomOffset, true,
|
||||
TAG_DONE);
|
||||
if (ammo2 != NULL && ammo2!=ammo1)
|
||||
{
|
||||
// Draw secondary ammo just above the primary ammo
|
||||
DrINumberOuter (ammo2->Amount, -29, -56);
|
||||
screen->DrawTexture (TexMan(ammo2->Icon), -14, -63,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_CenterBottomOffset, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw inventory
|
||||
if (CPlayer->inventorytics == 0)
|
||||
{
|
||||
if (ArtifactFlash)
|
||||
{
|
||||
screen->DrawTexture (Images[imgARTIBOX], -61, -31,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, TRANSLUC50,
|
||||
TAG_DONE);
|
||||
screen->DrawTexture (Images[imgUSEARTIA + ArtifactFlash], -61, -31,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
TAG_DONE);
|
||||
}
|
||||
else if (CPlayer->mo->InvSel != NULL)
|
||||
{
|
||||
screen->DrawTexture (Images[imgARTIBOX], -61, -31,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, TRANSLUC50,
|
||||
TAG_DONE);
|
||||
screen->DrawTexture (TexMan(CPlayer->mo->InvSel->Icon), -61, -31,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_ColorOverlay, CPlayer->mo->InvSel->Amount > 0 ? 0 : DIM_OVERLAY,
|
||||
TAG_DONE);
|
||||
if (CPlayer->mo->InvSel->Amount != 1)
|
||||
{
|
||||
DrSmallNumberOuter (CPlayer->mo->InvSel->Amount, -46, -9, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CPlayer->mo->InvFirst = ValidateInvFirst (7);
|
||||
i = 0;
|
||||
if (CPlayer->mo->InvFirst != NULL)
|
||||
{
|
||||
for (item = CPlayer->mo->InvFirst; item != NULL && i < 7; item = item->NextInv(), ++i)
|
||||
{
|
||||
screen->DrawTexture (Images[imgARTIBOX], -100+i*31, -32,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
DTA_Alpha, HX_SHADOW,
|
||||
TAG_DONE);
|
||||
screen->DrawTexture (TexMan(item->Icon), -100+i*31, -32,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
DTA_ColorOverlay, item->Amount > 0 ? 0 : DIM_OVERLAY,
|
||||
TAG_DONE);
|
||||
if (item->Amount != 1)
|
||||
{
|
||||
DrSmallNumberOuter (item->Amount, -84+i*31, -10, true);
|
||||
}
|
||||
if (item == CPlayer->mo->InvSel)
|
||||
{
|
||||
screen->DrawTexture (Images[imgSELECTBOX], -100+i*31, -3,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
// Is there something to the left?
|
||||
if (CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
|
||||
{
|
||||
screen->DrawTexture (Images[!(gametic & 4) ?
|
||||
imgINVLFGEM1 : imgINVLFGEM2], -112, -33,
|
||||
DTA_HUDRules, HUD_HorizCenter, TAG_DONE);
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (item != NULL)
|
||||
{
|
||||
screen->DrawTexture (Images[!(gametic & 4) ?
|
||||
imgINVRTGEM1 : imgINVRTGEM2], 119, -33,
|
||||
DTA_HUDRules, HUD_HorizCenter, TAG_DONE);
|
||||
}
|
||||
}
|
||||
for (; i < 7; i++)
|
||||
{
|
||||
screen->DrawTexture (Images[imgARTIBOX], -100+i*31, -32,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
DTA_Alpha, HX_SHADOW,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC FlashItem
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FlashItem (const PClass *itemtype)
|
||||
{
|
||||
ArtifactFlash = 4;
|
||||
}
|
||||
|
||||
static const char patcharti[][10];
|
||||
static const char ammopic[][10];
|
||||
|
||||
TObjPtr<AInventory> oldarti;
|
||||
TObjPtr<AAmmo> oldammo1, oldammo2;
|
||||
int oldammocount1, oldammocount2;
|
||||
int oldartiCount;
|
||||
int oldfrags;
|
||||
int oldarmor;
|
||||
int oldhealth;
|
||||
int oldlife;
|
||||
int oldkeys;
|
||||
|
||||
enum
|
||||
{
|
||||
imgLTFACE,
|
||||
imgRTFACE,
|
||||
imgBARBACK,
|
||||
imgINVBAR,
|
||||
imgCHAIN,
|
||||
imgSTATBAR,
|
||||
imgLIFEGEM,
|
||||
imgLTFCTOP,
|
||||
imgRTFCTOP,
|
||||
imgSELECTBOX,
|
||||
imgINVLFGEM1,
|
||||
imgINVLFGEM2,
|
||||
imgINVRTGEM1,
|
||||
imgINVRTGEM2,
|
||||
imgBLACKSQ,
|
||||
imgARMCLEAR,
|
||||
imgCHAINBACK,
|
||||
imgGOD1,
|
||||
imgGOD2,
|
||||
imgUSEARTIA,
|
||||
imgUSEARTIB,
|
||||
imgUSEARTIC,
|
||||
imgUSEARTID,
|
||||
imgYKEYICON,
|
||||
imgGKEYICON,
|
||||
imgBKEYICON,
|
||||
imgARTIBOX,
|
||||
imgPTN1,
|
||||
imgPTN2,
|
||||
imgPTN3,
|
||||
|
||||
NUM_HERETICSB_IMAGES
|
||||
};
|
||||
|
||||
FImageCollection Images;
|
||||
|
||||
int HealthMarker;
|
||||
int ChainWiggle;
|
||||
int ArtifactFlash;
|
||||
|
||||
char HealthRefresh;
|
||||
char ArtiRefresh;
|
||||
char FragHealthRefresh;
|
||||
char KeysRefresh;
|
||||
char AmmoRefresh;
|
||||
char ArmorRefresh;
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS(DHereticStatusBar)
|
||||
DECLARE_POINTER(oldarti)
|
||||
DECLARE_POINTER(oldammo1)
|
||||
DECLARE_POINTER(oldammo2)
|
||||
END_POINTERS
|
||||
|
||||
DBaseStatusBar *CreateHereticStatusBar ()
|
||||
{
|
||||
return new DHereticStatusBar;
|
||||
}
|
|
@ -31,6 +31,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PClassActor *hammertime = PClass::FindActor("HammerPuff");
|
||||
|
||||
damage = 25+(pr_maceatk()&15);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
|
@ -38,21 +40,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("HammerPuff"), true);
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
// player->mo->angle = R_PointToAngle2(player->mo->x,
|
||||
// player->mo->y, linetarget->x, linetarget->y);
|
||||
goto macedone;
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
goto macedone;
|
||||
}
|
||||
}
|
||||
angle = player->mo->angle-i*(ANG45/16);
|
||||
slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("HammerPuff"), true);
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
// player->mo->angle = R_PointToAngle2(player->mo->x,
|
||||
// player->mo->y, linetarget->x, linetarget->y);
|
||||
goto macedone;
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
goto macedone;
|
||||
}
|
||||
}
|
||||
}
|
||||
// didn't find any creatures, so try to strike any walls
|
||||
|
@ -60,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
|
||||
angle = player->mo->angle;
|
||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("HammerPuff"));
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime);
|
||||
macedone:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
int i;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
PClassActor *puff;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
|
@ -66,13 +67,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
pmo = player->mo;
|
||||
damage = 20+(pr_staffcheck()&15);
|
||||
max = pmo->GetMaxHealth();
|
||||
puff = PClass::FindActor("CStaffPuff");
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
angle = pmo->angle+i*(ANG45/16);
|
||||
slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget);
|
||||
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y,
|
||||
linetarget->x, linetarget->y);
|
||||
if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER)
|
||||
|
@ -96,7 +98,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget);
|
||||
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y,
|
||||
linetarget->x, linetarget->y);
|
||||
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
|
||||
|
|
|
@ -242,27 +242,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
|||
slope = P_AimLineAttack (pmo, angle, AXERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
useMana++;
|
||||
goto axedone;
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
useMana++;
|
||||
goto axedone;
|
||||
}
|
||||
angle = pmo->angle-i*(ANG45/16);
|
||||
slope = P_AimLineAttack (pmo, angle, AXERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true);
|
||||
if (linetarget->flags3&MF3_ISMONSTER)
|
||||
P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
if (linetarget->flags3&MF3_ISMONSTER)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
useMana++;
|
||||
goto axedone;
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
useMana++;
|
||||
goto axedone;
|
||||
}
|
||||
}
|
||||
// didn't find any creatures, so try to strike any walls
|
||||
|
|
|
@ -51,29 +51,35 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
|||
{
|
||||
angle = pmo->angle + i*(ANG45/32);
|
||||
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj(linetarget, angle, power);
|
||||
}
|
||||
pmo->special1 = false; // Don't throw a hammer
|
||||
goto hammerdone;
|
||||
}
|
||||
pmo->special1 = false; // Don't throw a hammer
|
||||
goto hammerdone;
|
||||
}
|
||||
angle = pmo->angle-i*(ANG45/32);
|
||||
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||
if(linetarget)
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj(linetarget, angle, power);
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj(linetarget, angle, power);
|
||||
}
|
||||
pmo->special1 = false; // Don't throw a hammer
|
||||
goto hammerdone;
|
||||
}
|
||||
pmo->special1 = false; // Don't throw a hammer
|
||||
goto hammerdone;
|
||||
}
|
||||
}
|
||||
// didn't find any targets in meleerange, so set to throw out a hammer
|
||||
|
|
|
@ -167,13 +167,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
power = 6*FRACUNIT;
|
||||
pufftype = PClass::FindActor("HammerPuff");
|
||||
}
|
||||
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
goto punchdone;
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
goto punchdone;
|
||||
}
|
||||
angle = pmo->angle-i * (ANG45/16);
|
||||
slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &linetarget);
|
||||
|
@ -186,13 +189,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
power = 6*FRACUNIT;
|
||||
pufftype = PClass::FindActor("HammerPuff");
|
||||
}
|
||||
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
goto punchdone;
|
||||
}
|
||||
AdjustPlayerAngle (pmo, linetarget);
|
||||
goto punchdone;
|
||||
}
|
||||
}
|
||||
// didn't find any creatures, so try to strike any walls
|
||||
|
|
|
@ -83,7 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
|
|||
|
||||
if (self->args[3]-- <= 0)
|
||||
{
|
||||
self->SetStateNF (self->FindState(NAME_Death));
|
||||
self->SetState (self->FindState(NAME_Death), true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
|||
damage = 3+(pr_snoutattack()&3);
|
||||
angle = player->mo->angle;
|
||||
slope = P_AimLineAttack(player->mo, angle, MELEERANGE, &linetarget);
|
||||
puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true);
|
||||
puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &linetarget);
|
||||
S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM);
|
||||
if(linetarget)
|
||||
{
|
||||
|
|
|
@ -115,9 +115,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
|
|||
{ // Reached it's target height
|
||||
actor->args[0] = 1;
|
||||
if (actor->args[1])
|
||||
actor->SetStateNF (actor->FindState ("BloodThrustInit2"));
|
||||
actor->SetState (actor->FindState ("BloodThrustInit2"), true);
|
||||
else
|
||||
actor->SetStateNF (actor->FindState ("ThrustInit2"));
|
||||
actor->SetState (actor->FindState ("ThrustInit2"), true);
|
||||
}
|
||||
|
||||
// Lose the dirt clump
|
||||
|
@ -142,9 +142,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
|
|||
{
|
||||
self->args[0] = 0;
|
||||
if (self->args[1])
|
||||
self->SetStateNF (self->FindState ("BloodThrustInit1"));
|
||||
self->SetState (self->FindState ("BloodThrustInit1"), true);
|
||||
else
|
||||
self->SetStateNF (self->FindState ("ThrustInit1"));
|
||||
self->SetState (self->FindState ("ThrustInit1"), true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -419,15 +419,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType();
|
||||
|
||||
//Did the user specify a "base"
|
||||
if(cstype == GAME_Heretic)
|
||||
{
|
||||
StatusBar = CreateHereticStatusBar();
|
||||
}
|
||||
else if(cstype == GAME_Hexen)
|
||||
{
|
||||
StatusBar = CreateHexenStatusBar();
|
||||
}
|
||||
else if(cstype == GAME_Strife)
|
||||
if(cstype == GAME_Strife)
|
||||
{
|
||||
StatusBar = CreateStrifeStatusBar();
|
||||
}
|
||||
|
@ -442,18 +434,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
}
|
||||
if (StatusBar == NULL)
|
||||
{
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
if (gameinfo.gametype & (GAME_DoomChex|GAME_Heretic|GAME_Hexen))
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar (SCRIPT_DEFAULT);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Heretic)
|
||||
{
|
||||
StatusBar = CreateHereticStatusBar ();
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
StatusBar = CreateHexenStatusBar ();
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
StatusBar = CreateStrifeStatusBar ();
|
||||
|
@ -545,10 +529,8 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
static FString nextlevel;
|
||||
static int startpos; // [RH] Support for multiple starts per level
|
||||
extern int NoWipe; // [RH] Don't wipe when travelling in hubs
|
||||
static bool startkeepfacing; // [RH] Support for keeping your facing angle
|
||||
static bool resetinventory; // Reset the inventory to the player's default for the next level
|
||||
static int changeflags;
|
||||
static bool unloading;
|
||||
static bool g_nomonsters;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -559,8 +541,7 @@ static bool g_nomonsters;
|
|||
//==========================================================================
|
||||
|
||||
|
||||
void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nextSkill,
|
||||
bool nointermission, bool resetinv, bool nomonsters)
|
||||
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill)
|
||||
{
|
||||
level_info_t *nextinfo = NULL;
|
||||
|
||||
|
@ -589,25 +570,32 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
|
|||
if (nextSkill != -1)
|
||||
NextSkill = nextSkill;
|
||||
|
||||
g_nomonsters = nomonsters;
|
||||
|
||||
if (nointermission) level.flags |= LEVEL_NOINTERMISSION;
|
||||
if (flags & CHANGELEVEL_NOINTERMISSION)
|
||||
{
|
||||
level.flags |= LEVEL_NOINTERMISSION;
|
||||
}
|
||||
|
||||
cluster_info_t *thiscluster = FindClusterInfo (level.cluster);
|
||||
cluster_info_t *nextcluster = nextinfo? FindClusterInfo (nextinfo->cluster) : NULL;
|
||||
|
||||
startpos = position;
|
||||
startkeepfacing = keepFacing;
|
||||
gameaction = ga_completed;
|
||||
resetinventory = resetinv;
|
||||
|
||||
if (nextinfo != NULL)
|
||||
{
|
||||
if (thiscluster != nextcluster || (thiscluster && !(thiscluster->flags & CLUSTER_HUB)))
|
||||
{
|
||||
resetinventory |= !!(nextinfo->flags2 & LEVEL2_RESETINVENTORY);
|
||||
if (nextinfo->flags2 & LEVEL2_RESETINVENTORY)
|
||||
{
|
||||
flags |= CHANGELEVEL_RESETINVENTORY;
|
||||
}
|
||||
if (nextinfo->flags2 & LEVEL2_RESETHEALTH)
|
||||
{
|
||||
flags |= CHANGELEVEL_RESETHEALTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
changeflags = flags;
|
||||
|
||||
bglobal.End(); //Added by MC:
|
||||
|
||||
|
@ -683,12 +671,12 @@ const char *G_GetSecretExitMap()
|
|||
|
||||
void G_ExitLevel (int position, bool keepFacing)
|
||||
{
|
||||
G_ChangeLevel(G_GetExitMap(), position, keepFacing);
|
||||
G_ChangeLevel(G_GetExitMap(), position, keepFacing ? CHANGELEVEL_KEEPFACING : 0);
|
||||
}
|
||||
|
||||
void G_SecretExitLevel (int position)
|
||||
{
|
||||
G_ChangeLevel(G_GetSecretExitMap(), position, false);
|
||||
G_ChangeLevel(G_GetSecretExitMap(), position, 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -802,7 +790,7 @@ void G_DoCompleted (void)
|
|||
{
|
||||
if (playeringame[i])
|
||||
{ // take away appropriate inventory
|
||||
G_PlayerFinishLevel (i, mode, resetinventory);
|
||||
G_PlayerFinishLevel (i, mode, changeflags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -943,7 +931,7 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
players[i].fragcount = 0;
|
||||
}
|
||||
|
||||
if (g_nomonsters)
|
||||
if (changeflags & CHANGELEVEL_NOMONSTERS)
|
||||
{
|
||||
level.flags2 |= LEVEL2_NOMONSTERS;
|
||||
}
|
||||
|
@ -1180,7 +1168,7 @@ void G_FinishTravel ()
|
|||
// The player being spawned here is a short lived dummy and
|
||||
// must not start any ENTER script or big problems will happen.
|
||||
pawndup = P_SpawnPlayer (&playerstarts[pawn->player - players], true);
|
||||
if (!startkeepfacing)
|
||||
if (!changeflags & CHANGELEVEL_KEEPFACING)
|
||||
{
|
||||
pawn->angle = pawndup->angle;
|
||||
pawn->pitch = pawndup->pitch;
|
||||
|
@ -1476,8 +1464,8 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|||
P_SerializeThinkers (arc, hubLoad);
|
||||
P_SerializeWorld (arc);
|
||||
P_SerializePolyobjs (arc);
|
||||
P_SerializeSubsectors(arc);
|
||||
StatusBar->Serialize (arc);
|
||||
//SerializeInterpolations (arc);
|
||||
|
||||
arc << level.total_monsters << level.total_items << level.total_secrets;
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ enum ELevelFlags
|
|||
|
||||
LEVEL_SPECLOWERFLOOR = 0x00000100,
|
||||
LEVEL_SPECOPENDOOR = 0x00000200,
|
||||
LEVEL_SPECLOWERFLOORTOHIGHEST= 0x00000300,
|
||||
LEVEL_SPECACTIONSMASK = 0x00000300,
|
||||
|
||||
LEVEL_MONSTERSTELEFRAG = 0x00000400,
|
||||
|
@ -198,6 +199,7 @@ enum ELevelFlags
|
|||
LEVEL2_SMOOTHLIGHTING = 0x01000000, // Level uses the smooth lighting feature.
|
||||
LEVEL2_POLYGRIND = 0x02000000, // Polyobjects grind corpses to gibs.
|
||||
LEVEL2_RESETINVENTORY = 0x04000000, // Resets player inventory when starting this level (unless in a hub)
|
||||
LEVEL2_RESETHEALTH = 0x08000000, // Resets player health when starting this level (unless in a hub)
|
||||
};
|
||||
|
||||
|
||||
|
@ -236,6 +238,7 @@ struct FOptionalMapinfoDataPtr
|
|||
};
|
||||
|
||||
typedef TMap<FName, FOptionalMapinfoDataPtr> FOptData;
|
||||
typedef TMap<int, FName> FMusicMap;
|
||||
|
||||
struct level_info_t
|
||||
{
|
||||
|
@ -295,6 +298,7 @@ struct level_info_t
|
|||
float teamdamage;
|
||||
|
||||
FOptData optdata;
|
||||
FMusicMap MusicMap;
|
||||
|
||||
TArray<FSpecialAction> specialactions;
|
||||
|
||||
|
@ -486,8 +490,17 @@ void G_SecretExitLevel (int position);
|
|||
const char *G_GetExitMap();
|
||||
const char *G_GetSecretExitMap();
|
||||
|
||||
void G_ChangeLevel(const char * levelname, int position, bool keepFacing, int nextSkill=-1,
|
||||
bool nointermission=false, bool resetinventory=false, bool nomonsters=false);
|
||||
enum
|
||||
{
|
||||
CHANGELEVEL_KEEPFACING = 1,
|
||||
CHANGELEVEL_RESETINVENTORY = 2,
|
||||
CHANGELEVEL_NOMONSTERS = 4,
|
||||
CHANGELEVEL_CHANGESKILL = 8,
|
||||
CHANGELEVEL_NOINTERMISSION = 16,
|
||||
CHANGELEVEL_RESETHEALTH = 32,
|
||||
};
|
||||
|
||||
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill=-1);
|
||||
|
||||
void G_SetForEndGame (char *nextmap);
|
||||
|
||||
|
@ -533,9 +546,11 @@ enum ESkillProperty
|
|||
SKILLP_ACSReturn,
|
||||
SKILLP_MonsterHealth,
|
||||
SKILLP_FriendlyHealth,
|
||||
SKILLP_NoPain
|
||||
SKILLP_NoPain,
|
||||
SKILLP_ArmorFactor
|
||||
};
|
||||
int G_SkillProperty(ESkillProperty prop);
|
||||
const char * G_SkillName();
|
||||
|
||||
typedef TMap<FName, FString> SkillMenuNames;
|
||||
|
||||
|
@ -556,8 +571,8 @@ struct FSkillInfo
|
|||
int SpawnFilter;
|
||||
int ACSReturn;
|
||||
FString MenuName;
|
||||
FString PicName;
|
||||
SkillMenuNames MenuNamesForPlayerClass;
|
||||
bool MenuNameIsLump;
|
||||
bool MustConfirm;
|
||||
FString MustConfirmText;
|
||||
char Shortcut;
|
||||
|
@ -567,6 +582,7 @@ struct FSkillInfo
|
|||
fixed_t MonsterHealth;
|
||||
fixed_t FriendlyHealth;
|
||||
bool NoPain;
|
||||
fixed_t ArmorFactor;
|
||||
|
||||
FSkillInfo() {}
|
||||
FSkillInfo(const FSkillInfo &other)
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include "doomstat.h"
|
||||
#include "d_player.h"
|
||||
#include "autosegs.h"
|
||||
#include "version.h"
|
||||
#include "v_text.h"
|
||||
|
||||
int FindEndSequence (int type, const char *picname);
|
||||
|
||||
|
@ -1324,6 +1326,7 @@ MapFlagHandlers[] =
|
|||
{ "specialaction_exitlevel", MITYPE_SCFLAGS, 0, ~LEVEL_SPECACTIONSMASK },
|
||||
{ "specialaction_opendoor", MITYPE_SCFLAGS, LEVEL_SPECOPENDOOR, ~LEVEL_SPECACTIONSMASK },
|
||||
{ "specialaction_lowerfloor", MITYPE_SCFLAGS, LEVEL_SPECLOWERFLOOR, ~LEVEL_SPECACTIONSMASK },
|
||||
{ "specialaction_lowerfloortohighest",MITYPE_SCFLAGS,LEVEL_SPECLOWERFLOORTOHIGHEST, ~LEVEL_SPECACTIONSMASK },
|
||||
{ "specialaction_killmonsters", MITYPE_SETFLAG, LEVEL_SPECKILLMONSTERS, 0 },
|
||||
{ "lightning", MITYPE_SETFLAG, LEVEL_STARTLIGHTNING, 0 },
|
||||
{ "smoothlighting", MITYPE_SETFLAG2, LEVEL2_SMOOTHLIGHTING, 0 },
|
||||
|
@ -1372,6 +1375,7 @@ MapFlagHandlers[] =
|
|||
{ "grinding_polyobj", MITYPE_SETFLAG2, LEVEL2_POLYGRIND, 0 },
|
||||
{ "no_grinding_polyobj", MITYPE_CLRFLAG2, LEVEL2_POLYGRIND, 0 },
|
||||
{ "resetinventory", MITYPE_SETFLAG2, LEVEL2_RESETINVENTORY, 0 },
|
||||
{ "resethealth", MITYPE_SETFLAG2, LEVEL2_RESETHEALTH, 0 },
|
||||
{ "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 },
|
||||
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
||||
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX},
|
||||
|
@ -1399,6 +1403,8 @@ MapFlagHandlers[] =
|
|||
{ "compat_corpsegibs", MITYPE_COMPATFLAG, COMPATF_CORPSEGIBS},
|
||||
{ "compat_noblockfriends", MITYPE_COMPATFLAG, COMPATF_NOBLOCKFRIENDS},
|
||||
{ "compat_spritesort", MITYPE_COMPATFLAG, COMPATF_SPRITESORT},
|
||||
{ "compat_light", MITYPE_COMPATFLAG, COMPATF_LIGHT},
|
||||
{ "compat_polyobj", MITYPE_COMPATFLAG, COMPATF_POLYOBJ},
|
||||
{ "cd_start_track", MITYPE_EATNEXT, 0, 0 },
|
||||
{ "cd_end1_track", MITYPE_EATNEXT, 0, 0 },
|
||||
{ "cd_end2_track", MITYPE_EATNEXT, 0, 0 },
|
||||
|
@ -1799,6 +1805,7 @@ void FMapInfoParser::ParseEpisodeInfo ()
|
|||
EpisodeMenu[i].fulltext = !picisgfx;
|
||||
EpisodeNoSkill[i] = noskill;
|
||||
strncpy (EpisodeMaps[i], map, 8);
|
||||
EpisodeMaps[i][8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1861,6 +1868,15 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i
|
|||
{
|
||||
sc.ScriptError("include file '%s' not found", sc.String);
|
||||
}
|
||||
if (Wads.GetLumpFile(sc.LumpNum) != Wads.GetLumpFile(inclump))
|
||||
{
|
||||
// Do not allow overriding includes from the default MAPINFO
|
||||
if (Wads.GetLumpFile(sc.LumpNum) == 0)
|
||||
{
|
||||
I_FatalError("File %s is overriding core lump %s.",
|
||||
Wads.GetWadFullName(Wads.GetLumpFile(inclump)), sc.String);
|
||||
}
|
||||
}
|
||||
FScanner saved_sc = sc;
|
||||
ParseMapInfo(inclump, gamedefaults, defaultinfo);
|
||||
sc = saved_sc;
|
||||
|
@ -1952,12 +1968,18 @@ void G_ParseMapInfo (const char *basemapinfo)
|
|||
|
||||
atterm(ClearEpisodes);
|
||||
|
||||
// Parse the default MAPINFO for the current game.
|
||||
// Parse the default MAPINFO for the current game. This lump *MUST* come from zdoom.pk3.
|
||||
if (basemapinfo != NULL)
|
||||
{
|
||||
FMapInfoParser parse;
|
||||
level_info_t defaultinfo;
|
||||
parse.ParseMapInfo(Wads.GetNumForFullName(basemapinfo), gamedefaults, defaultinfo);
|
||||
int baselump = Wads.GetNumForFullName(basemapinfo);
|
||||
if (Wads.GetLumpFile(baselump) > 0)
|
||||
{
|
||||
I_FatalError("File %s is overriding core lump %s.",
|
||||
Wads.GetWadFullName(Wads.GetLumpFile(baselump)), basemapinfo);
|
||||
}
|
||||
parse.ParseMapInfo(baselump, gamedefaults, defaultinfo);
|
||||
}
|
||||
|
||||
static const char *mapinfonames[] = { "MAPINFO", "ZMAPINFO", NULL };
|
||||
|
|
|
@ -200,7 +200,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
|
|||
&& pr_minotaurdecide() < 150)
|
||||
{ // Charge attack
|
||||
// Don't call the state function right away
|
||||
self->SetStateNF (self->FindState ("Charge"));
|
||||
self->SetState (self->FindState ("Charge"), true);
|
||||
self->flags |= MF_SKULLFLY;
|
||||
if (!friendly)
|
||||
{ // Heretic's Minotaur is invulnerable during charge attack
|
||||
|
@ -473,9 +473,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
|
|||
{
|
||||
// Turn
|
||||
if (pr_minotaurroam() & 1)
|
||||
self->movedir = (++self->movedir)%8;
|
||||
self->movedir = (self->movedir + 1) % 8;
|
||||
else
|
||||
self->movedir = (self->movedir+7)%8;
|
||||
self->movedir = (self->movedir + 7) % 8;
|
||||
FaceMovementDirection (self);
|
||||
}
|
||||
return 0;
|
||||
|
@ -552,11 +552,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
|
|||
|
||||
if (self->target)
|
||||
{
|
||||
self->SetStateNF (self->SeeState);
|
||||
self->SetState (self->SeeState, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->SetStateNF (self->FindState ("Roam"));
|
||||
self->SetState (self->FindState ("Roam"), true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,10 +57,8 @@ IMPLEMENT_CLASS (ASwitchingDecoration)
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
|
||||
void A_Unblock(AActor *self, bool drop)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (self->flags & MF_STEALTH)
|
||||
{
|
||||
|
@ -70,18 +68,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
|
|||
|
||||
self->flags &= ~MF_SOLID;
|
||||
|
||||
// If the self has a conversation that sets an item to drop, drop that.
|
||||
// If the actor has a conversation that sets an item to drop, drop that.
|
||||
if (self->Conversation != NULL && self->Conversation->DropType != NULL)
|
||||
{
|
||||
P_DropItem (self, self->Conversation->DropType, -1, 256);
|
||||
self->Conversation = NULL;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
self->Conversation = NULL;
|
||||
|
||||
// If the self has attached metadata for items to drop, drop those.
|
||||
if (!self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB]
|
||||
// If the actor has attached metadata for items to drop, drop those.
|
||||
if (drop && !self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB]
|
||||
{
|
||||
DDropItem *di = self->GetDropItems();
|
||||
|
||||
|
@ -101,14 +99,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
A_Unblock(self, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Fall)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
CALL_ACTION(A_NoBlocking, self);
|
||||
A_Unblock(self, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -332,7 +335,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
|
|||
{
|
||||
CALL_ACTION(A_BossDeath, self);
|
||||
}
|
||||
CALL_ACTION(A_NoBlocking, self);
|
||||
A_Unblock(self, true);
|
||||
|
||||
self->SetState(self->FindState(NAME_Null));
|
||||
return 0;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "r_data.h"
|
||||
#include "a_pickups.h"
|
||||
#include "templates.h"
|
||||
#include "g_level.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLASS (AArmor)
|
||||
|
@ -84,6 +85,18 @@ bool ABasicArmor::HandlePickup (AInventory *item)
|
|||
// You shouldn't be picking up BasicArmor anyway.
|
||||
return true;
|
||||
}
|
||||
if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorBonus)) && !(item->ItemFlags & IF_IGNORESKILL))
|
||||
{
|
||||
ABasicArmorBonus *armor = static_cast<ABasicArmorBonus*>(item);
|
||||
|
||||
armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
|
||||
}
|
||||
else if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorPickup)) && !(item->ItemFlags & IF_IGNORESKILL))
|
||||
{
|
||||
ABasicArmorPickup *armor = static_cast<ABasicArmorPickup*>(item);
|
||||
|
||||
armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
return Inventory->HandlePickup (item);
|
||||
|
@ -198,10 +211,17 @@ void ABasicArmorPickup::Serialize (FArchive &arc)
|
|||
AInventory *ABasicArmorPickup::CreateCopy (AActor *other)
|
||||
{
|
||||
ABasicArmorPickup *copy = static_cast<ABasicArmorPickup *> (Super::CreateCopy (other));
|
||||
|
||||
if (!(ItemFlags & IF_IGNORESKILL))
|
||||
{
|
||||
SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
|
||||
}
|
||||
|
||||
copy->SavePercent = SavePercent;
|
||||
copy->SaveAmount = SaveAmount;
|
||||
copy->MaxAbsorb = MaxAbsorb;
|
||||
copy->MaxFullAbsorb = MaxFullAbsorb;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -272,6 +292,12 @@ void ABasicArmorBonus::Serialize (FArchive &arc)
|
|||
AInventory *ABasicArmorBonus::CreateCopy (AActor *other)
|
||||
{
|
||||
ABasicArmorBonus *copy = static_cast<ABasicArmorBonus *> (Super::CreateCopy (other));
|
||||
|
||||
if (!(ItemFlags & IF_IGNORESKILL))
|
||||
{
|
||||
SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
|
||||
}
|
||||
|
||||
copy->SavePercent = SavePercent;
|
||||
copy->SaveAmount = SaveAmount;
|
||||
copy->MaxSaveAmount = MaxSaveAmount;
|
||||
|
@ -279,6 +305,7 @@ AInventory *ABasicArmorBonus::CreateCopy (AActor *other)
|
|||
copy->BonusMax = BonusMax;
|
||||
copy->MaxAbsorb = MaxAbsorb;
|
||||
copy->MaxFullAbsorb = MaxFullAbsorb;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
|
|
@ -750,10 +750,6 @@ void APowerIronFeet::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
if (damageType == NAME_Drowning)
|
||||
{
|
||||
newdamage = 0;
|
||||
if (Owner->player != NULL)
|
||||
{
|
||||
Owner->player->mo->ResetAirSupply ();
|
||||
}
|
||||
}
|
||||
else if (Inventory != NULL)
|
||||
{
|
||||
|
@ -761,6 +757,21 @@ void APowerIronFeet::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerIronFeet :: DoEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerIronFeet::DoEffect ()
|
||||
{
|
||||
if (Owner->player != NULL)
|
||||
{
|
||||
Owner->player->mo->ResetAirSupply ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Strife Environment Suit Powerup -------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS (APowerMask)
|
||||
|
@ -993,6 +1004,12 @@ void APowerFlight::EndEffect ()
|
|||
|
||||
bool APowerFlight::DrawPowerup (int x, int y)
|
||||
{
|
||||
// If this item got a valid icon use that instead of the default spinning wings.
|
||||
if (Icon.isValid())
|
||||
{
|
||||
return Super::DrawPowerup(x, y);
|
||||
}
|
||||
|
||||
if (EffectTics > BLINKTHRESHOLD || !(EffectTics & 16))
|
||||
{
|
||||
FTextureID picnum = TexMan.CheckForTexture ("SPFLY0", FTexture::TEX_MiscPatch);
|
||||
|
|
|
@ -86,6 +86,7 @@ class APowerIronFeet : public APowerup
|
|||
DECLARE_CLASS (APowerIronFeet, APowerup)
|
||||
public:
|
||||
void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
||||
void DoEffect ();
|
||||
};
|
||||
|
||||
class APowerMask : public APowerIronFeet
|
||||
|
|
|
@ -72,7 +72,7 @@ void AFastProjectile::Tick ()
|
|||
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen
|
||||
}
|
||||
|
||||
if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm))
|
||||
if (!P_TryMove (this, x + xfrac,y + yfrac, true, NULL, tm))
|
||||
{ // Blocked move
|
||||
if (!(flags3 & MF3_SKYEXPLODE))
|
||||
{
|
||||
|
@ -158,10 +158,13 @@ void AFastProjectile::Effect()
|
|||
if (name != NAME_None)
|
||||
{
|
||||
fixed_t hitz = z-8*FRACUNIT;
|
||||
|
||||
if (hitz < floorz)
|
||||
{
|
||||
hitz = floorz;
|
||||
}
|
||||
// Do not clip this offset to the floor.
|
||||
hitz += GetClass()->MissileHeight;
|
||||
|
||||
PClassActor *trail = PClass::FindActor(name);
|
||||
if (trail != NULL)
|
||||
|
|
|
@ -19,7 +19,12 @@ struct OneKey
|
|||
|
||||
bool check(AActor *owner)
|
||||
{
|
||||
return !!owner->FindInventory(key);
|
||||
// P_GetMapColorForKey() checks the key directly
|
||||
if (owner->IsKindOf (RUNTIME_CLASS(AKey)))
|
||||
return owner->IsA(key);
|
||||
// Other calls check an actor that may have a key in its inventory.
|
||||
else
|
||||
return !!owner->FindInventory(key);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -99,15 +99,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
|
|||
p->morphTics = (duration) ? duration : MORPHTICS;
|
||||
|
||||
// [MH] Used by SBARINFO to speed up face drawing
|
||||
p->MorphedPlayerClass = 0;
|
||||
for (unsigned int i = 1; i < PlayerClasses.Size(); i++)
|
||||
{
|
||||
if (PlayerClasses[i].Type == spawntype)
|
||||
{
|
||||
p->MorphedPlayerClass = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->MorphedPlayerClass = spawntype;
|
||||
|
||||
p->MorphStyle = style;
|
||||
p->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog);
|
||||
|
@ -149,19 +141,6 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
|
|||
p->camera = morphed;
|
||||
}
|
||||
morphed->ScoreIcon = actor->ScoreIcon; // [GRB]
|
||||
|
||||
// [MH]
|
||||
// If the player that was morphed is the one
|
||||
// taking events, set up the face, if any;
|
||||
// this is only needed for old-skool skins
|
||||
// and for the original DOOM status bar.
|
||||
if (p == &players[consoleplayer])
|
||||
{
|
||||
if (spawntype->Face.IsNotEmpty() && strcmp(spawntype->Face, "None") != 0)
|
||||
{
|
||||
StatusBar->SetFace(&skins[p->MorphedPlayerClass]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -307,7 +286,6 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
|
|||
}
|
||||
}
|
||||
}
|
||||
StatusBar->SetFace(&skins[skinindex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -401,6 +401,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition)
|
|||
self->z += FloatBobOffsets[(self->FloatBobPhase + level.maptime) & 63];
|
||||
}
|
||||
}
|
||||
self->SetOrigin (self->x, self->y, self->z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -935,7 +936,7 @@ void AInventory::Touch (AActor *toucher)
|
|||
{
|
||||
const char * message = PickupMessage ();
|
||||
|
||||
if (toucher->CheckLocalView (consoleplayer)
|
||||
if (message != NULL && *message != 0 && toucher->CheckLocalView (consoleplayer)
|
||||
&& (StaticLastMessageTic != gametic || StaticLastMessage != message))
|
||||
{
|
||||
StaticLastMessageTic = gametic;
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
bool AddWeapon (const char *type);
|
||||
bool AddWeapon (PClassWeapon *type);
|
||||
void AddWeaponList (const char *list, bool clear);
|
||||
AWeapon *PickWeapon (player_t *player);
|
||||
AWeapon *PickWeapon (player_t *player, bool checkammo = false);
|
||||
int Size () const { return (int)Weapons.Size(); }
|
||||
int LocateWeapon (PClassWeapon *type);
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ class ARandomSpawner : public AActor
|
|||
{
|
||||
// copy everything relevant
|
||||
newmobj->SpawnAngle = newmobj->angle = angle;
|
||||
newmobj->SpawnPoint[2] = SpawnPoint[2];
|
||||
newmobj->special = special;
|
||||
newmobj->args[0] = args[0];
|
||||
newmobj->args[1] = args[1];
|
||||
|
@ -147,10 +148,10 @@ class ARandomSpawner : public AActor
|
|||
// a health set to -2 after spawning, for internal reasons.
|
||||
if (health != SpawnHealth()) newmobj->health = health;
|
||||
if (!(flags & MF_DROPPED)) newmobj->flags &= ~MF_DROPPED;
|
||||
// Handle special altitude flags
|
||||
// Handle special altitude flags
|
||||
if (newmobj->flags & MF_SPAWNCEILING)
|
||||
{
|
||||
newmobj->z = newmobj->ceilingz - newmobj->height;
|
||||
newmobj->z = newmobj->ceilingz - newmobj->height - SpawnPoint[2];
|
||||
}
|
||||
else if (newmobj->flags2 & MF2_SPAWNFLOAT)
|
||||
{
|
||||
|
@ -160,6 +161,7 @@ class ARandomSpawner : public AActor
|
|||
space -= 40*FRACUNIT;
|
||||
newmobj->z = MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT;
|
||||
}
|
||||
newmobj->z += SpawnPoint[2];
|
||||
}
|
||||
if (newmobj->flags & MF_MISSILE)
|
||||
P_CheckMissileSpawn(newmobj);
|
||||
|
|
|
@ -147,14 +147,20 @@ struct FSpotList
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ASpecialSpot *GetSpotWithMinDistance(fixed_t x, fixed_t y, fixed_t distance)
|
||||
ASpecialSpot *GetSpotWithMinMaxDistance(fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist)
|
||||
{
|
||||
if (Spots.Size() == 0) return NULL;
|
||||
int i = pr_spot() % Spots.Size();
|
||||
int initial = i;
|
||||
|
||||
while (P_AproxDistance(Spots[i]->x - x, Spots[i]->y - y) < distance)
|
||||
fixed_t distance;
|
||||
|
||||
while (true)
|
||||
{
|
||||
distance = P_AproxDistance(Spots[i]->x - x, Spots[i]->y - y);
|
||||
|
||||
if ((distance >= mindist) && ((maxdist == 0) || (distance <= maxdist))) break;
|
||||
|
||||
i = (i+1) % Spots.Size();
|
||||
if (i == initial) return NULL;
|
||||
}
|
||||
|
@ -329,10 +335,10 @@ ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter)
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ASpecialSpot *DSpotState::GetSpotWithMinDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t distance)
|
||||
ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist)
|
||||
{
|
||||
FSpotList *list = FindSpotList(type);
|
||||
if (list != NULL) return list->GetSpotWithMinDistance(x, y, distance);
|
||||
if (list != NULL) return list->GetSpotWithMinMaxDistance(x, y, mindist, maxdist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
bool RemoveSpot(ASpecialSpot *spot);
|
||||
void Serialize(FArchive &arc);
|
||||
ASpecialSpot *GetNextInList(const PClass *type, int skipcounter);
|
||||
ASpecialSpot *GetSpotWithMinDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t distance);
|
||||
ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist);
|
||||
ASpecialSpot *GetRandomSpot(const PClass *type, bool onlyonce = false);
|
||||
};
|
||||
|
||||
|
|
|
@ -771,7 +771,7 @@ int FWeaponSlot::LocateWeapon(PClassWeapon *type)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
||||
AWeapon *FWeaponSlot::PickWeapon(player_t *player, bool checkammo)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
@ -795,9 +795,12 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
|||
{
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory(Weapons[j].Type));
|
||||
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
return weap;
|
||||
if (!checkammo || weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -807,9 +810,12 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
|||
{
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory(Weapons[i].Type));
|
||||
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
return weap;
|
||||
if (!checkammo || weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
return player->ReadyWeapon;
|
||||
|
|
|
@ -165,7 +165,7 @@ struct FMugShotFrame
|
|||
|
||||
FMugShotFrame();
|
||||
~FMugShotFrame();
|
||||
FTexture *GetTexture(const char *default_face, FPlayerSkin *skin, int random, int level=0,
|
||||
FTexture *GetTexture(const char *default_face, const char *skin_face, int random, int level=0,
|
||||
int direction=0, bool usesLevels=false, bool health2=false, bool healthspecial=false,
|
||||
bool directional=false);
|
||||
};
|
||||
|
@ -189,9 +189,9 @@ struct FMugShotState
|
|||
void Tick();
|
||||
void Reset();
|
||||
FMugShotFrame &GetCurrentFrame() { return Frames[Position]; }
|
||||
FTexture *GetCurrentFrameTexture(const char *default_face, FPlayerSkin *skin, int level=0, int direction=0)
|
||||
FTexture *GetCurrentFrameTexture(const char *default_face, const char *skin_face, int level=0, int direction=0)
|
||||
{
|
||||
return GetCurrentFrame().GetTexture(default_face, skin, Random, level, direction, bUsesLevels, bHealth2, bHealthSpecial, bDirectional);
|
||||
return GetCurrentFrame().GetTexture(default_face, skin_face, Random, level, direction, bUsesLevels, bHealth2, bHealthSpecial, bDirectional);
|
||||
}
|
||||
private:
|
||||
FMugShotState();
|
||||
|
@ -215,6 +215,7 @@ class FMugShot
|
|||
|
||||
FMugShot();
|
||||
void Grin(bool grin=true) { bEvilGrin = grin; }
|
||||
void Reset();
|
||||
void Tick(player_t *player);
|
||||
bool SetState(const char *state_name, bool wait_till_done=false, bool reset=false);
|
||||
int UpdateState(player_t *player, StateFlags stateflags=STANDARD);
|
||||
|
@ -275,7 +276,7 @@ public:
|
|||
ST_DEADFACE = ST_GODFACE + 1
|
||||
};
|
||||
|
||||
DBaseStatusBar (int reltop);
|
||||
DBaseStatusBar (int reltop, int hres=320, int vres=200);
|
||||
void Destroy ();
|
||||
|
||||
void SetScaled (bool scale, bool force=false);
|
||||
|
@ -300,8 +301,6 @@ public:
|
|||
virtual void AttachToPlayer (player_t *player);
|
||||
virtual void FlashCrosshair ();
|
||||
virtual void BlendView (float blend[4]);
|
||||
virtual void SetFace (void *skn); // Takes a FPlayerSkin as input
|
||||
virtual void AddFaceToImageCollection (void *skn, FImageCollection *images); // Takes a FPlayerSkin as input
|
||||
virtual void NewGame ();
|
||||
virtual void ScreenSizeChanged ();
|
||||
virtual void MultiplayerChanged ();
|
||||
|
@ -334,14 +333,13 @@ protected:
|
|||
|
||||
void GetCurrentAmmo (AAmmo *&ammo1, AAmmo *&ammo2, int &ammocount1, int &ammocount2) const;
|
||||
|
||||
void AddFaceToImageCollectionActual (void *skn, FImageCollection *images, bool isDoom);
|
||||
|
||||
public:
|
||||
AInventory *ValidateInvFirst (int numVisible) const;
|
||||
void DrawCrosshair ();
|
||||
|
||||
int ST_X, ST_Y;
|
||||
int RelTop;
|
||||
int HorizontalResolution, VirticalResolution;
|
||||
bool Scaled;
|
||||
bool Centering;
|
||||
bool FixedOrigin;
|
||||
|
@ -378,8 +376,6 @@ extern DBaseStatusBar *StatusBar;
|
|||
|
||||
// Status bar factories -----------------------------------------------------
|
||||
|
||||
DBaseStatusBar *CreateHereticStatusBar();
|
||||
DBaseStatusBar *CreateHexenStatusBar();
|
||||
DBaseStatusBar *CreateStrifeStatusBar();
|
||||
DBaseStatusBar *CreateCustomStatusBar(int script=0);
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ FMugShotFrame::~FMugShotFrame()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FTexture *FMugShotFrame::GetTexture(const char *default_face, FPlayerSkin *skin, int random, int level,
|
||||
FTexture *FMugShotFrame::GetTexture(const char *default_face, const char *skin_face, int random, int level,
|
||||
int direction, bool uses_levels, bool health2, bool healthspecial, bool directional)
|
||||
{
|
||||
int index = !directional ? random % Graphic.Size() : direction;
|
||||
|
@ -84,7 +84,7 @@ FTexture *FMugShotFrame::GetTexture(const char *default_face, FPlayerSkin *skin,
|
|||
{
|
||||
index = Graphic.Size() - 1;
|
||||
}
|
||||
FString sprite(skin->face[0] != 0 ? skin->face : default_face, 3);
|
||||
FString sprite(skin_face != NULL && skin_face[0] != 0 ? skin_face : default_face, 3);
|
||||
sprite += Graphic[index];
|
||||
if (uses_levels) //change the last character to the level
|
||||
{
|
||||
|
@ -221,6 +221,17 @@ int FindMugShotStateIndex(FName state)
|
|||
//===========================================================================
|
||||
|
||||
FMugShot::FMugShot()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FMugShot :: Reset
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMugShot::Reset()
|
||||
{
|
||||
FaceHealth = -1;
|
||||
bEvilGrin = false;
|
||||
|
@ -492,8 +503,8 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu
|
|||
}
|
||||
if (CurrentState != NULL)
|
||||
{
|
||||
FPlayerSkin *skin = &skins[player->morphTics ? player->MorphedPlayerClass : player->userinfo.skin];
|
||||
return CurrentState->GetCurrentFrameTexture(default_face, skin, level, angle);
|
||||
const char *skin_face = player->morphTics ? player->MorphedPlayerClass->Face : skins[player->userinfo.skin].face;
|
||||
return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -57,16 +57,8 @@
|
|||
#include "g_level.h"
|
||||
#include "v_palette.h"
|
||||
#include "p_acs.h"
|
||||
|
||||
#define ADJUST_RELCENTER(x, y, outX, outY) \
|
||||
if(x.RelCenter()) \
|
||||
outX = *x + SCREENWIDTH/(hud_scale ? CleanXfac*2 : 2); \
|
||||
else \
|
||||
outX = *x; \
|
||||
if(y.RelCenter()) \
|
||||
outY = *y + SCREENHEIGHT/(hud_scale ? CleanYfac*2 : 2); \
|
||||
else \
|
||||
outY = *y;
|
||||
#include "gstrings.h"
|
||||
#include "version.h"
|
||||
|
||||
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
||||
enum
|
||||
|
@ -189,8 +181,8 @@ class SBarInfoCommand
|
|||
}
|
||||
}
|
||||
|
||||
if(!fullScreenOffsets)
|
||||
y.SetCoord((negative ? -sc.Number : sc.Number) - (200 - script->height));
|
||||
//if(!fullScreenOffsets)
|
||||
// y.SetCoord((negative ? -sc.Number : sc.Number) - (200 - script->height));
|
||||
}
|
||||
EColorRange GetTranslation(FScanner &sc)
|
||||
{
|
||||
|
@ -213,60 +205,107 @@ class SBarInfoCommand
|
|||
class SBarInfoCommandFlowControl : public SBarInfoCommand
|
||||
{
|
||||
public:
|
||||
SBarInfoCommandFlowControl(SBarInfo *script) : SBarInfoCommand(script) {}
|
||||
SBarInfoCommandFlowControl(SBarInfo *script) : SBarInfoCommand(script), truth(false) {}
|
||||
~SBarInfoCommandFlowControl()
|
||||
{
|
||||
for(unsigned int i = 0;i < commands.Size();i++)
|
||||
delete commands[i];
|
||||
for(unsigned int i = 0;i < 2;i++)
|
||||
{
|
||||
for(unsigned int j = 0;j < commands[i].Size();j++)
|
||||
delete commands[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
|
||||
{
|
||||
for(unsigned int i = 0;i < commands.Size();i++)
|
||||
commands[i]->Draw(block, statusBar);
|
||||
for(unsigned int i = 0;i < commands[truth].Size();i++)
|
||||
commands[truth][i]->Draw(block, statusBar);
|
||||
}
|
||||
int NumCommands() const { return commands.Size(); }
|
||||
int NumCommands() const { return commands[truth].Size(); }
|
||||
void Parse(FScanner &sc, bool fullScreenOffsets)
|
||||
{
|
||||
sc.MustGetToken('{');
|
||||
bool elseBlock = false;
|
||||
SBarInfoCommand *cmd = NULL;
|
||||
while((cmd = NextCommand(sc)) != NULL)
|
||||
// Should loop no more than twice.
|
||||
while(true)
|
||||
{
|
||||
cmd->Parse(sc, fullScreenOffsets);
|
||||
commands.Push(cmd);
|
||||
if(sc.CheckToken('{'))
|
||||
{
|
||||
while((cmd = NextCommand(sc)) != NULL)
|
||||
{
|
||||
cmd->Parse(sc, fullScreenOffsets);
|
||||
commands[!elseBlock].Push(cmd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((cmd = NextCommand(sc)) != NULL)
|
||||
{
|
||||
cmd->Parse(sc, fullScreenOffsets);
|
||||
commands[!elseBlock].Push(cmd);
|
||||
}
|
||||
else
|
||||
sc.ScriptError("Missing command for flow control statement.");
|
||||
}
|
||||
|
||||
if(!elseBlock && sc.CheckToken(TK_Else))
|
||||
{
|
||||
elseBlock = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Reset()
|
||||
{
|
||||
for(unsigned int i = 0;i < commands.Size();i++)
|
||||
commands[i]->Reset();
|
||||
for(unsigned int i = 0;i < 2;i++)
|
||||
{
|
||||
for(unsigned int j = 0;j < commands[i].Size();j++)
|
||||
commands[i][j]->Reset();
|
||||
}
|
||||
}
|
||||
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
|
||||
{
|
||||
for(unsigned int i = 0;i < commands.Size();i++)
|
||||
commands[i]->Tick(block, statusBar, hudChanged);
|
||||
for(unsigned int i = 0;i < commands[truth].Size();i++)
|
||||
commands[truth][i]->Tick(block, statusBar, hudChanged);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetTruth(bool truth, const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
|
||||
{
|
||||
// If there is no change we don't need to do anything. Do note
|
||||
// that this should not change more than once per tick. If it does
|
||||
// there may be cosmetic problems.
|
||||
if(this->truth == truth)
|
||||
return;
|
||||
|
||||
this->truth = truth;
|
||||
if(block != NULL)
|
||||
Tick(block, statusBar, true);
|
||||
}
|
||||
|
||||
private:
|
||||
SBarInfoCommand *NextCommand(FScanner &sc);
|
||||
|
||||
TArray<SBarInfoCommand *> commands;
|
||||
bool truth;
|
||||
TArray<SBarInfoCommand *> commands[2];
|
||||
};
|
||||
|
||||
class SBarInfoMainBlock : public SBarInfoCommandFlowControl
|
||||
{
|
||||
public:
|
||||
SBarInfoMainBlock(SBarInfo *script) : SBarInfoCommandFlowControl(script),
|
||||
alpha(FRACUNIT), forceScaled(false), fullScreenOffsets(false)
|
||||
alpha(FRACUNIT), currentAlpha(FRACUNIT), forceScaled(false),
|
||||
fullScreenOffsets(false)
|
||||
{
|
||||
SetTruth(true, NULL, NULL);
|
||||
}
|
||||
|
||||
int Alpha() const { return alpha; }
|
||||
int Alpha() const { return currentAlpha; }
|
||||
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, int xOffset, int yOffset, int alpha)
|
||||
{
|
||||
this->xOffset = xOffset;
|
||||
this->yOffset = yOffset;
|
||||
this->alpha = alpha;
|
||||
this->currentAlpha = fixed_t((((double) this->alpha / (double) FRACUNIT) * ((double) alpha / (double) FRACUNIT)) * FRACUNIT);
|
||||
SBarInfoCommandFlowControl::Draw(this, statusBar);
|
||||
}
|
||||
bool ForceScaled() const { return forceScaled; }
|
||||
|
@ -299,8 +338,9 @@ class SBarInfoMainBlock : public SBarInfoCommandFlowControl
|
|||
int XOffset() const { return xOffset; }
|
||||
int YOffset() const { return yOffset; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
int alpha;
|
||||
int currentAlpha;
|
||||
bool forceScaled;
|
||||
bool fullScreenOffsets;
|
||||
int xOffset;
|
||||
|
@ -320,6 +360,7 @@ enum //Key words
|
|||
SBARINFO_COMPLETEBORDER,
|
||||
SBARINFO_MONOSPACEFONTS,
|
||||
SBARINFO_LOWERHEALTHCAP,
|
||||
SBARINFO_RESOLUTION,
|
||||
SBARINFO_STATUSBAR,
|
||||
SBARINFO_MUGSHOT,
|
||||
SBARINFO_CREATEPOPUP,
|
||||
|
@ -347,6 +388,7 @@ static const char *SBarInfoTopLevel[] =
|
|||
"completeborder",
|
||||
"monospacefonts",
|
||||
"lowerhealthcap",
|
||||
"resolution",
|
||||
"statusbar",
|
||||
"mugshot",
|
||||
"createpopup",
|
||||
|
@ -428,6 +470,7 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
ParseSBarInfo(lump);
|
||||
continue;
|
||||
}
|
||||
int baselump = -2;
|
||||
switch(sc.MustMatchString(SBarInfoTopLevel))
|
||||
{
|
||||
case SBARINFO_BASE:
|
||||
|
@ -436,21 +479,36 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
sc.MustGetToken(TK_Identifier);
|
||||
if(sc.Compare("Doom"))
|
||||
{
|
||||
int lump = Wads.CheckNumForFullName("sbarinfo/doom.txt", true);
|
||||
if(lump == -1)
|
||||
sc.ScriptError("Standard Doom Status Bar not found.");
|
||||
ParseSBarInfo(lump);
|
||||
baselump = Wads.CheckNumForFullName("sbarinfo/doom.txt", true);
|
||||
}
|
||||
else if(sc.Compare("Heretic"))
|
||||
gameType = GAME_Heretic;
|
||||
{
|
||||
baselump = Wads.CheckNumForFullName("sbarinfo/heretic.txt", true);
|
||||
}
|
||||
else if(sc.Compare("Hexen"))
|
||||
gameType = GAME_Hexen;
|
||||
{
|
||||
baselump = Wads.CheckNumForFullName("sbarinfo/hexen.txt", true);
|
||||
}
|
||||
else if(sc.Compare("Strife"))
|
||||
gameType = GAME_Strife;
|
||||
else if(sc.Compare("None"))
|
||||
gameType = GAME_Any;
|
||||
else
|
||||
sc.ScriptError("Bad game name: %s", sc.String);
|
||||
// If one of the standard status bar should be loaded, baselump has been set to a different value.
|
||||
if (baselump != -2)
|
||||
{
|
||||
if(baselump == -1)
|
||||
{
|
||||
sc.ScriptError("Standard %s status bar not found.", sc.String);
|
||||
}
|
||||
else if (Wads.GetLumpFile(baselump) > 0)
|
||||
{
|
||||
I_FatalError("File %s is overriding core lump sbarinfo/%s.txt.",
|
||||
Wads.GetWadFullName(Wads.GetLumpFile(baselump)), sc.String);
|
||||
}
|
||||
ParseSBarInfo(baselump);
|
||||
}
|
||||
sc.MustGetToken(';');
|
||||
break;
|
||||
case SBARINFO_HEIGHT:
|
||||
|
@ -518,6 +576,19 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_StringConst); //Don't tell anyone we're just ignoring this ;)
|
||||
}
|
||||
if(sc.CheckToken(','))
|
||||
{
|
||||
// Character alignment
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
if(sc.Compare("left"))
|
||||
spacingAlignment = ALIGN_LEFT;
|
||||
else if(sc.Compare("center"))
|
||||
spacingAlignment = ALIGN_CENTER;
|
||||
else if(sc.Compare("right"))
|
||||
spacingAlignment = ALIGN_RIGHT;
|
||||
else
|
||||
sc.ScriptError("Unknown alignment '%s'.", sc.String);
|
||||
}
|
||||
sc.MustGetToken(';');
|
||||
break;
|
||||
case SBARINFO_LOWERHEALTHCAP:
|
||||
|
@ -532,6 +603,14 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
}
|
||||
sc.MustGetToken(';');
|
||||
break;
|
||||
case SBARINFO_RESOLUTION:
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
resW = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
resH = sc.Number;
|
||||
sc.MustGetToken(';');
|
||||
break;
|
||||
case SBARINFO_STATUSBAR:
|
||||
{
|
||||
if(!baseSet) //If the user didn't explicitly define a base, do so now.
|
||||
|
@ -615,6 +694,13 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
sc.MustGetToken(TK_IntConst);
|
||||
popup.speed = sc.Number;
|
||||
}
|
||||
else if(sc.Compare("pushup"))
|
||||
{
|
||||
popup.transition = Popup::TRANSITION_PUSHUP;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
popup.speed = sc.Number;
|
||||
}
|
||||
else if(sc.Compare("fade"))
|
||||
{
|
||||
popup.transition = Popup::TRANSITION_FADE;
|
||||
|
@ -707,6 +793,9 @@ void SBarInfo::Init()
|
|||
armorInterpolationSpeed = 8;
|
||||
height = 0;
|
||||
spacingCharacter = '\0';
|
||||
spacingAlignment = ALIGN_CENTER;
|
||||
resW = 320;
|
||||
resH = 200;
|
||||
|
||||
for(unsigned int i = 0;i < NUMHUDS;i++)
|
||||
huds[i] = new SBarInfoMainBlock(this);
|
||||
|
@ -722,78 +811,79 @@ SBarInfo::~SBarInfo()
|
|||
}
|
||||
|
||||
//Popup
|
||||
Popup::Popup()
|
||||
Popup::Popup() : transition(TRANSITION_NONE), opened(false), moving(false),
|
||||
height(320), width(200), speed(0), speed2(0), alpha(FRACUNIT), x(320),
|
||||
y(200), displacementX(0), displacementY(0)
|
||||
{
|
||||
transition = TRANSITION_NONE;
|
||||
height = 320;
|
||||
width = 200;
|
||||
speed = 0;
|
||||
x = 320;
|
||||
y = 200;
|
||||
alpha = FRACUNIT;
|
||||
opened = false;
|
||||
moving = false;
|
||||
}
|
||||
|
||||
void Popup::init()
|
||||
{
|
||||
x = width;
|
||||
y = height;
|
||||
if(transition == TRANSITION_SLIDEINBOTTOM)
|
||||
switch(transition)
|
||||
{
|
||||
x = 0;
|
||||
}
|
||||
else if(transition == TRANSITION_FADE)
|
||||
{
|
||||
alpha = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
case TRANSITION_SLIDEINBOTTOM:
|
||||
case TRANSITION_PUSHUP:
|
||||
x = 0;
|
||||
break;
|
||||
case TRANSITION_FADE:
|
||||
alpha = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Popup::tick()
|
||||
{
|
||||
if(transition == TRANSITION_SLIDEINBOTTOM)
|
||||
switch(transition)
|
||||
{
|
||||
if(moving)
|
||||
{
|
||||
if(opened)
|
||||
y -= clamp(height + (y - height), 1, speed);
|
||||
case TRANSITION_SLIDEINBOTTOM:
|
||||
case TRANSITION_PUSHUP:
|
||||
if(moving)
|
||||
{
|
||||
int oldY = y;
|
||||
if(opened)
|
||||
y -= clamp(height + (y - height), 1, speed);
|
||||
else
|
||||
y += clamp(height - y, 1, speed);
|
||||
if(transition == TRANSITION_PUSHUP)
|
||||
displacementY += y - oldY;
|
||||
}
|
||||
if(y != 0 && y != height)
|
||||
moving = true;
|
||||
else
|
||||
y += clamp(height - y, 1, speed);
|
||||
}
|
||||
if(y != 0 && y != height)
|
||||
moving = true;
|
||||
else
|
||||
moving = false;
|
||||
}
|
||||
else if(transition == TRANSITION_FADE)
|
||||
{
|
||||
if(moving)
|
||||
{
|
||||
if(opened)
|
||||
alpha = clamp(alpha + speed, 0, FRACUNIT);
|
||||
moving = false;
|
||||
break;
|
||||
case TRANSITION_FADE:
|
||||
if(moving)
|
||||
{
|
||||
if(opened)
|
||||
alpha = clamp(alpha + speed, 0, FRACUNIT);
|
||||
else
|
||||
alpha = clamp(alpha - speed2, 0, FRACUNIT);
|
||||
}
|
||||
if(alpha == 0 || alpha == FRACUNIT)
|
||||
moving = false;
|
||||
else
|
||||
alpha = clamp(alpha - speed2, 0, FRACUNIT);
|
||||
}
|
||||
if(alpha == 0 || alpha == FRACUNIT)
|
||||
moving = true;
|
||||
break;
|
||||
default:
|
||||
if(opened)
|
||||
{
|
||||
y = 0;
|
||||
x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = height;
|
||||
x = width;
|
||||
}
|
||||
moving = false;
|
||||
else
|
||||
moving = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(opened)
|
||||
{
|
||||
y = 0;
|
||||
x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = height;
|
||||
x = width;
|
||||
}
|
||||
moving = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,6 +909,16 @@ int Popup::getAlpha(int maxAlpha)
|
|||
return fixed_t((a * b) * FRACUNIT);
|
||||
}
|
||||
|
||||
int Popup::getXDisplacement()
|
||||
{
|
||||
return displacementX;
|
||||
}
|
||||
|
||||
int Popup::getYDisplacement()
|
||||
{
|
||||
return displacementY;
|
||||
}
|
||||
|
||||
void Popup::open()
|
||||
{
|
||||
opened = true;
|
||||
|
@ -833,11 +933,23 @@ void Popup::close()
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, const double &xScale, const double &yScale)
|
||||
{
|
||||
if(relX)
|
||||
outX = x + (SCREENWIDTH/(hud_scale ? xScale*2 : 2));
|
||||
else
|
||||
outX = x;
|
||||
if(relY)
|
||||
outY = y + (SCREENHEIGHT/(hud_scale ? yScale*2 : 2));
|
||||
else
|
||||
outY = y;
|
||||
}
|
||||
|
||||
class DSBarInfo : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DSBarInfo, DBaseStatusBar)
|
||||
public:
|
||||
DSBarInfo (SBarInfo *script=NULL) : DBaseStatusBar(script->height),
|
||||
DSBarInfo (SBarInfo *script=NULL) : DBaseStatusBar(script->height, script->resW, script->resH),
|
||||
ammo1(NULL), ammo2(NULL), ammocount1(0), ammocount2(0), armor(NULL),
|
||||
pendingPopup(POP_None), currentPopup(POP_None), lastHud(-1),
|
||||
lastInventoryBar(NULL), lastPopup(NULL)
|
||||
|
@ -861,10 +973,6 @@ public:
|
|||
{
|
||||
patchnames[i+script->Images.Size()] = InventoryBarLumps[i];
|
||||
}
|
||||
for (i = 0;i < numskins;i++)
|
||||
{
|
||||
AddFaceToImageCollection (&skins[i], &Images);
|
||||
}
|
||||
invBarOffset = script->Images.Size();
|
||||
Images.Init(&patchnames[0], patchnames.Size());
|
||||
}
|
||||
|
@ -918,8 +1026,13 @@ public:
|
|||
armor = CPlayer->mo->FindInventory<ABasicArmor>();
|
||||
if(hud != lastHud)
|
||||
script->huds[hud]->Tick(NULL, this, true);
|
||||
script->huds[hud]->Draw(NULL, this, 0, 0, FRACUNIT);
|
||||
|
||||
if(currentPopup != POP_None && !script->huds[hud]->FullScreenOffsets())
|
||||
script->huds[hud]->Draw(NULL, this, script->popups[currentPopup-1].getXDisplacement(), script->popups[currentPopup-1].getYDisplacement(), FRACUNIT);
|
||||
else
|
||||
script->huds[hud]->Draw(NULL, this, 0, 0, FRACUNIT);
|
||||
lastHud = hud;
|
||||
|
||||
if(CPlayer->inventorytics > 0 && !(level.flags & LEVEL_NOINVENTORYBAR) && (state == HUD_StatusBar || state == HUD_Fullscreen))
|
||||
{
|
||||
SBarInfoMainBlock *inventoryBar = state == HUD_StatusBar ? script->huds[STBAR_INVENTORY] : script->huds[STBAR_INVENTORYFULLSCREEN];
|
||||
|
@ -1030,53 +1143,58 @@ public:
|
|||
if (texture == NULL)
|
||||
return;
|
||||
|
||||
double dx = *x;
|
||||
double dy = *y;
|
||||
|
||||
if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER)
|
||||
{
|
||||
x -= (texture->GetScaledWidth()/2)-texture->LeftOffset;
|
||||
y -= (texture->GetScaledHeight()/2)-texture->TopOffset;
|
||||
dx -= (texture->GetScaledWidthDouble()/2.0)-texture->LeftOffset;
|
||||
dy -= (texture->GetScaledHeightDouble()/2.0)-texture->TopOffset;
|
||||
}
|
||||
|
||||
x += xOffset;
|
||||
y += yOffset;
|
||||
int w, h;
|
||||
dx += xOffset;
|
||||
dy += yOffset;
|
||||
double w, h;
|
||||
if(!fullScreenOffsets)
|
||||
{
|
||||
fixed_t tmp = 0;
|
||||
// I'll handle the conversion from fixed to int myself for more control
|
||||
fixed_t fx = (x + ST_X).Coordinate() << FRACBITS;
|
||||
fixed_t fy = (y + ST_Y).Coordinate() << FRACBITS;
|
||||
fixed_t fw = (forceWidth <= -1 ? texture->GetScaledWidth() : forceWidth) << FRACBITS;
|
||||
fixed_t fh = (forceHeight <= -1 ? texture->GetScaledHeight() : forceHeight) << FRACBITS;
|
||||
fixed_t fcx = cx == 0 ? 0 : fx + cx - (texture->GetScaledLeftOffset() << FRACBITS);
|
||||
fixed_t fcy = cy == 0 ? 0 : fy + cy - (texture->GetScaledTopOffset() << FRACBITS);
|
||||
fixed_t fcr = fx + fw - cr;
|
||||
fixed_t fcb = fy + fh - cb;
|
||||
double tmp = 0;
|
||||
dx += ST_X;
|
||||
dy += ST_Y - (Scaled ? script->resH : 200) + script->height;
|
||||
w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth;
|
||||
h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight;
|
||||
double dcx = cx == 0 ? 0 : dx + ((double) cx / FRACUNIT) - texture->GetScaledLeftOffsetDouble();
|
||||
double dcy = cy == 0 ? 0 : dy + ((double) cy / FRACUNIT) - texture->GetScaledTopOffsetDouble();
|
||||
double dcr = cr == 0 ? INT_MAX : dx + w - ((double) cr / FRACUNIT);
|
||||
double dcb = cb == 0 ? INT_MAX : dy + h - ((double) cb / FRACUNIT);
|
||||
|
||||
if(Scaled)
|
||||
{
|
||||
if(cx != 0 || cy != 0)
|
||||
screen->VirtualToRealCoordsFixed(fcx, fcy, tmp, tmp, 320, 200, true);
|
||||
screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true);
|
||||
if(cr != 0 || cb != 0 || clearDontDraw)
|
||||
screen->VirtualToRealCoordsFixed(fcr, fcb, tmp, tmp, 320, 200, true);
|
||||
screen->VirtualToRealCoordsFixed(fx, fy, fw, fh, 320, 200, true);
|
||||
screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true);
|
||||
}
|
||||
// Round to nearest
|
||||
w = (fw + (FRACUNIT>>1)) >> FRACBITS;
|
||||
h = (fh + (FRACUNIT>>1)) >> FRACBITS;
|
||||
cr = cr != 0 ? fcr >> FRACBITS : INT_MAX;
|
||||
cb = cb != 0 ? fcb >> FRACBITS : INT_MAX;
|
||||
else
|
||||
{
|
||||
dy += 200 - script->resH;
|
||||
dcy += 200 - script->resH;
|
||||
dcb += 200 - script->resH;
|
||||
}
|
||||
|
||||
if(clearDontDraw)
|
||||
screen->Clear(MAX<fixed_t>(fx, fcx)>>FRACBITS, MAX<fixed_t>(fy, fcy)>>FRACBITS, fcr>>FRACBITS, fcb>>FRACBITS, GPalette.BlackIndex, 0);
|
||||
screen->Clear(static_cast<int>(MAX<double>(dx, dcx)), static_cast<int>(MAX<double>(dy, dcy)), static_cast<int>(dcr), static_cast<int>(dcb), GPalette.BlackIndex, 0);
|
||||
else
|
||||
{
|
||||
if(alphaMap)
|
||||
{
|
||||
screen->DrawTexture(texture, (fx >> FRACBITS), (fy >> FRACBITS),
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_ClipLeft, fcx>>FRACBITS,
|
||||
DTA_ClipTop, fcy>>FRACBITS,
|
||||
DTA_ClipRight, cr,
|
||||
DTA_ClipBottom, cb,
|
||||
screen->DrawTexture(texture, dx, dy,
|
||||
DTA_DestWidthF, w,
|
||||
DTA_DestHeightF, h,
|
||||
DTA_ClipLeft, static_cast<int>(dcx),
|
||||
DTA_ClipTop, static_cast<int>(dcy),
|
||||
DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)),
|
||||
DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)),
|
||||
DTA_Translation, translate ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
||||
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
|
||||
|
@ -1087,13 +1205,13 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
screen->DrawTexture(texture, (fx >> FRACBITS), (fy >> FRACBITS),
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_ClipLeft, fcx>>FRACBITS,
|
||||
DTA_ClipTop, fcy>>FRACBITS,
|
||||
DTA_ClipRight, cr,
|
||||
DTA_ClipBottom, cb,
|
||||
screen->DrawTexture(texture, dx, dy,
|
||||
DTA_DestWidthF, w,
|
||||
DTA_DestHeightF, h,
|
||||
DTA_ClipLeft, static_cast<int>(dcx),
|
||||
DTA_ClipTop, static_cast<int>(dcy),
|
||||
DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)),
|
||||
DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)),
|
||||
DTA_Translation, translate ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
||||
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
|
||||
|
@ -1104,69 +1222,87 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
int rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX;
|
||||
ADJUST_RELCENTER(x,y,rx,ry)
|
||||
double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX;
|
||||
|
||||
w = (forceWidth <= -1 ? texture->GetScaledWidth() : forceWidth);
|
||||
h = (forceHeight <= -1 ? texture->GetScaledHeight() : forceHeight);
|
||||
double xScale = !hud_scale ? 1.0 : (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW;
|
||||
double yScale = !hud_scale ? 1.0 : (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENHEIGHT/(double) script->resH;
|
||||
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale);
|
||||
|
||||
// We can't use DTA_HUDRules since it forces a width and height.
|
||||
// Translation: No high res.
|
||||
bool xright = rx < 0;
|
||||
bool ybot = ry < 0;
|
||||
|
||||
w = (forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth);
|
||||
h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight);
|
||||
if(vid_fps && rx < 0 && ry >= 0)
|
||||
ry += 10;
|
||||
if(hud_scale)
|
||||
{
|
||||
rx *= xScale;
|
||||
ry *= yScale;
|
||||
w *= xScale;
|
||||
h *= yScale;
|
||||
}
|
||||
if(xright)
|
||||
rx = SCREENWIDTH + rx;
|
||||
if(ybot)
|
||||
ry = SCREENHEIGHT + ry;
|
||||
|
||||
// Check for clipping
|
||||
if(cx != 0 || cy != 0 || cr != 0 || cb != 0)
|
||||
{
|
||||
rcx = cx == 0 ? 0 : rx+(cx>>FRACBITS);
|
||||
rcy = cy == 0 ? 0 : ry+(cy>>FRACBITS);
|
||||
rcr = cr == 0 ? INT_MAX : rx+w-(cr>>FRACBITS);
|
||||
rcb = cb == 0 ? INT_MAX : ry+h-(cb>>FRACBITS);
|
||||
rcx = cx == 0 ? 0 : rx+(((double) cx/FRACUNIT)*xScale);
|
||||
rcy = cy == 0 ? 0 : ry+(((double) cy/FRACUNIT)*yScale);
|
||||
rcr = cr == 0 ? INT_MAX : rx+w-(((double) cr/FRACUNIT)*xScale);
|
||||
rcb = cb == 0 ? INT_MAX : ry+h-(((double) cb/FRACUNIT)*yScale);
|
||||
|
||||
// Fix the clipping for fullscreenoffsets.
|
||||
if(ry < 0)
|
||||
/*if(ry < 0)
|
||||
{
|
||||
if(rcy != 0)
|
||||
rcy = hud_scale ? SCREENHEIGHT + (rcy*CleanYfac) : SCREENHEIGHT + rcy;
|
||||
rcy = hud_scale ? SCREENHEIGHT + (int) (rcy*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcy;
|
||||
if(rcb != INT_MAX)
|
||||
rcb = hud_scale ? SCREENHEIGHT + (rcb*CleanYfac) : SCREENHEIGHT + rcb;
|
||||
rcb = hud_scale ? SCREENHEIGHT + (int) (rcb*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcb;
|
||||
}
|
||||
else if(hud_scale)
|
||||
{
|
||||
rcy *= CleanYfac;
|
||||
rcy *= (int) (CleanYfac*200.0/script->resH);
|
||||
if(rcb != INT_MAX)
|
||||
rcb *= CleanYfac;
|
||||
rcb *= (int) (CleanYfac*200.0/script->resH);
|
||||
}
|
||||
if(rx < 0)
|
||||
{
|
||||
if(rcx != 0)
|
||||
rcx = hud_scale ? SCREENWIDTH + (rcx*CleanXfac) : SCREENWIDTH + rcx;
|
||||
rcx = hud_scale ? SCREENWIDTH + (int) (rcx*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcx;
|
||||
if(rcr != INT_MAX)
|
||||
rcr = hud_scale ? SCREENWIDTH + (rcr*CleanXfac) : SCREENWIDTH + rcr;
|
||||
rcr = hud_scale ? SCREENWIDTH + (int) (rcr*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcr;
|
||||
}
|
||||
else if(hud_scale)
|
||||
{
|
||||
rcx *= CleanXfac;
|
||||
rcx *= (int) (CleanXfac*320.0/script->resW);
|
||||
if(rcr != INT_MAX)
|
||||
rcr *= CleanXfac;
|
||||
}
|
||||
rcr *= (int) (CleanXfac*320.0/script->resW);
|
||||
}*/
|
||||
}
|
||||
|
||||
if(clearDontDraw)
|
||||
{
|
||||
screen->Clear(rcx, rcy, MIN<int>(rcr, w*(hud_scale ? CleanXfac : 1)), MIN<int>(rcb, h*(hud_scale ? CleanYfac : 1)), GPalette.BlackIndex, 0);
|
||||
}
|
||||
screen->Clear(static_cast<int>(rcx), static_cast<int>(rcy), static_cast<int>(MIN<double>(rcr, rcx+w)), static_cast<int>(MIN<double>(rcb, rcy+h)), GPalette.BlackIndex, 0);
|
||||
else
|
||||
{
|
||||
if(alphaMap)
|
||||
{
|
||||
screen->DrawTexture(texture, rx, ry,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_ClipLeft, rcx,
|
||||
DTA_ClipTop, rcy,
|
||||
DTA_ClipRight, rcr,
|
||||
DTA_ClipBottom, rcb,
|
||||
DTA_DestWidthF, w,
|
||||
DTA_DestHeightF, h,
|
||||
DTA_ClipLeft, static_cast<int>(rcx),
|
||||
DTA_ClipTop, static_cast<int>(rcy),
|
||||
DTA_ClipRight, static_cast<int>(rcr),
|
||||
DTA_ClipBottom, static_cast<int>(rcb),
|
||||
DTA_Translation, translate ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
||||
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, alpha,
|
||||
DTA_AlphaChannel, alphaMap,
|
||||
DTA_FillColor, 0,
|
||||
|
@ -1175,16 +1311,15 @@ public:
|
|||
else
|
||||
{
|
||||
screen->DrawTexture(texture, rx, ry,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_ClipLeft, rcx,
|
||||
DTA_ClipTop, rcy,
|
||||
DTA_ClipRight, rcr,
|
||||
DTA_ClipBottom, rcb,
|
||||
DTA_DestWidthF, w,
|
||||
DTA_DestHeightF, h,
|
||||
DTA_ClipLeft, static_cast<int>(rcx),
|
||||
DTA_ClipTop, static_cast<int>(rcy),
|
||||
DTA_ClipRight, static_cast<int>(rcr),
|
||||
DTA_ClipBottom, static_cast<int>(rcb),
|
||||
DTA_Translation, translate ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
||||
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
@ -1192,20 +1327,32 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void DrawString(FFont *font, const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false) const
|
||||
void DrawString(FFont *font, const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false, int shadowX=2, int shadowY=2) const
|
||||
{
|
||||
x += spacing;
|
||||
int ax = *x;
|
||||
int ay = *y;
|
||||
double ax = *x;
|
||||
double ay = *y;
|
||||
|
||||
double xScale = 1.0;
|
||||
double yScale = 1.0;
|
||||
|
||||
if(fullScreenOffsets)
|
||||
{
|
||||
ADJUST_RELCENTER(x,y,ax,ay)
|
||||
if(hud_scale)
|
||||
{
|
||||
xScale = (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW;
|
||||
yScale = (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENWIDTH/(double) script->resW;
|
||||
}
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale);
|
||||
}
|
||||
while(*str != '\0')
|
||||
{
|
||||
if(*str == ' ')
|
||||
{
|
||||
ax += font->GetSpaceWidth();
|
||||
if(script->spacingCharacter == '\0')
|
||||
ax += font->GetSpaceWidth();
|
||||
else
|
||||
ax += font->GetCharWidth((int) script->spacingCharacter);
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
|
@ -1223,65 +1370,77 @@ public:
|
|||
if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset
|
||||
ax += (character->LeftOffset+1); //ignore x offsets since we adapt to character size
|
||||
|
||||
int rx, ry, rw, rh;
|
||||
double rx, ry, rw, rh;
|
||||
rx = ax + xOffset;
|
||||
ry = ay + yOffset;
|
||||
rw = character->GetScaledWidth();
|
||||
rh = character->GetScaledHeight();
|
||||
rw = character->GetScaledWidthDouble();
|
||||
rh = character->GetScaledHeightDouble();
|
||||
|
||||
if(script->spacingCharacter != '\0')
|
||||
{
|
||||
double spacingSize = font->GetCharWidth((int) script->spacingCharacter);
|
||||
switch(script->spacingAlignment)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case SBarInfo::ALIGN_CENTER:
|
||||
rx += (spacingSize/2)-(rw/2);
|
||||
break;
|
||||
case SBarInfo::ALIGN_RIGHT:
|
||||
rx += spacingSize-rw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!fullScreenOffsets)
|
||||
{
|
||||
rx += ST_X;
|
||||
ry += ST_Y;
|
||||
ry += ST_Y - (Scaled ? script->resH : 200) + script->height;
|
||||
if(Scaled)
|
||||
screen->VirtualToRealCoordsInt(rx, ry, rw, rh, 320, 200, true);
|
||||
screen->VirtualToRealCoords(rx, ry, rw, rh, script->resW, script->resH, true);
|
||||
else
|
||||
{
|
||||
ry += (200 - script->resH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(vid_fps && ax < 0 && ay >= 0)
|
||||
ry += 10;
|
||||
|
||||
bool xright = rx < 0;
|
||||
bool ybot = ry < 0;
|
||||
|
||||
if(hud_scale)
|
||||
{
|
||||
rx *= xScale;
|
||||
ry *= yScale;
|
||||
rw *= xScale;
|
||||
rh *= yScale;
|
||||
}
|
||||
if(xright)
|
||||
rx = SCREENWIDTH + rx;
|
||||
if(ybot)
|
||||
ry = SCREENHEIGHT + ry;
|
||||
}
|
||||
if(drawshadow)
|
||||
{
|
||||
int salpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) HR_SHADOW / (double) FRACUNIT) * FRACUNIT);
|
||||
if(!fullScreenOffsets)
|
||||
{
|
||||
screen->DrawTexture(character, rx+2, ry+2,
|
||||
DTA_DestWidth, rw,
|
||||
DTA_DestHeight, rh,
|
||||
DTA_Alpha, salpha,
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawTexture(character, rx+2, ry+2,
|
||||
DTA_DestWidth, rw,
|
||||
DTA_DestHeight, rh,
|
||||
DTA_Alpha, salpha,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
if(!fullScreenOffsets)
|
||||
{
|
||||
screen->DrawTexture(character, rx, ry,
|
||||
DTA_DestWidth, rw,
|
||||
DTA_DestHeight, rh,
|
||||
DTA_Translation, font->GetColorTranslation(translation),
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawTexture(character, rx, ry,
|
||||
DTA_DestWidth, rw,
|
||||
DTA_DestHeight, rh,
|
||||
DTA_Translation, font->GetColorTranslation(translation),
|
||||
DTA_Alpha, alpha,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
double srx = rx + (shadowX*xScale);
|
||||
double sry = ry + (shadowY*yScale);
|
||||
screen->DrawTexture(character, srx, sry,
|
||||
DTA_DestWidthF, rw,
|
||||
DTA_DestHeightF, rh,
|
||||
DTA_Alpha, salpha,
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
}
|
||||
screen->DrawTexture(character, rx, ry,
|
||||
DTA_DestWidthF, rw,
|
||||
DTA_DestHeightF, rh,
|
||||
DTA_Translation, font->GetColorTranslation(translation),
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
if(script->spacingCharacter == '\0')
|
||||
ax += width + spacing - (character->LeftOffset+1);
|
||||
else //width gets changed at the call to GetChar()
|
||||
|
|
|
@ -52,6 +52,7 @@ struct Popup
|
|||
{
|
||||
TRANSITION_NONE,
|
||||
TRANSITION_SLIDEINBOTTOM,
|
||||
TRANSITION_PUSHUP,
|
||||
TRANSITION_FADE,
|
||||
};
|
||||
|
||||
|
@ -65,6 +66,8 @@ struct Popup
|
|||
int alpha;
|
||||
int x;
|
||||
int y;
|
||||
int displacementX;
|
||||
int displacementY;
|
||||
|
||||
Popup();
|
||||
void init();
|
||||
|
@ -75,10 +78,19 @@ struct Popup
|
|||
int getXOffset();
|
||||
int getYOffset();
|
||||
int getAlpha(int maxAlpha=FRACUNIT);
|
||||
int getXDisplacement();
|
||||
int getYDisplacement();
|
||||
};
|
||||
|
||||
struct SBarInfo
|
||||
{
|
||||
enum MonospaceAlignment
|
||||
{
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER,
|
||||
ALIGN_RIGHT
|
||||
};
|
||||
|
||||
TArray<FString> Images;
|
||||
SBarInfoMainBlock *huds[NUMHUDS];
|
||||
Popup popups[NUMPOPUPS];
|
||||
|
@ -88,11 +100,14 @@ struct SBarInfo
|
|||
bool completeBorder;
|
||||
bool lowerHealthCap;
|
||||
char spacingCharacter;
|
||||
MonospaceAlignment spacingAlignment;
|
||||
int interpolationSpeed;
|
||||
int armorInterpolationSpeed;
|
||||
int height;
|
||||
int gameType;
|
||||
FMugShot MugShot;
|
||||
int resW;
|
||||
int resH;
|
||||
|
||||
int GetGameType() { return gameType; }
|
||||
void ParseSBarInfo(int lump);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -175,7 +175,7 @@ void ST_LoadCrosshair(bool alwaysload)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DBaseStatusBar::DBaseStatusBar (int reltop)
|
||||
DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres)
|
||||
{
|
||||
Centering = false;
|
||||
FixedOrigin = false;
|
||||
|
@ -185,6 +185,8 @@ DBaseStatusBar::DBaseStatusBar (int reltop)
|
|||
Displacement = 0;
|
||||
CPlayer = NULL;
|
||||
ShowLog = false;
|
||||
HorizontalResolution = hres;
|
||||
VirticalResolution = vres;
|
||||
|
||||
SetScaled (st_scale);
|
||||
}
|
||||
|
@ -216,18 +218,20 @@ void DBaseStatusBar::Destroy ()
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
//[BL] Added force argument to have forcescaled mean forcescaled.
|
||||
// - Also, if the VirticalResolution is something other than the default (200)
|
||||
// We should always obey the value of scale.
|
||||
void DBaseStatusBar::SetScaled (bool scale, bool force)
|
||||
{
|
||||
Scaled = (RelTop != 0 || force) && (SCREENWIDTH != 320 && scale);
|
||||
Scaled = (RelTop != 0 || force) && ((SCREENWIDTH != 320 || HorizontalResolution != 320) && scale);
|
||||
|
||||
if (!Scaled)
|
||||
{
|
||||
ST_X = (SCREENWIDTH - 320) / 2;
|
||||
ST_X = (SCREENWIDTH - HorizontalResolution) / 2;
|
||||
ST_Y = SCREENHEIGHT - RelTop;
|
||||
::ST_Y = ST_Y;
|
||||
if (RelTop > 0)
|
||||
{
|
||||
Displacement = ((ST_Y * 200 / SCREENHEIGHT) - (200 - RelTop))*FRACUNIT/RelTop;
|
||||
Displacement = ((ST_Y * VirticalResolution / SCREENHEIGHT) - (VirticalResolution - RelTop))*FRACUNIT/RelTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -237,14 +241,14 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
|
|||
else
|
||||
{
|
||||
ST_X = 0;
|
||||
ST_Y = 200 - RelTop;
|
||||
ST_Y = VirticalResolution - RelTop;
|
||||
if (CheckRatio(SCREENWIDTH, SCREENHEIGHT) != 4)
|
||||
{ // Normal resolution
|
||||
::ST_Y = Scale (ST_Y, SCREENHEIGHT, 200);
|
||||
::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution);
|
||||
}
|
||||
else
|
||||
{ // 5:4 resolution
|
||||
::ST_Y = Scale(ST_Y - 100, SCREENHEIGHT*3, BaseRatioSizes[4][1]) + SCREENHEIGHT/2
|
||||
::ST_Y = Scale(ST_Y - VirticalResolution/2, SCREENHEIGHT*3, Scale(VirticalResolution, BaseRatioSizes[4][1], 200)) + SCREENHEIGHT/2
|
||||
+ (SCREENHEIGHT - SCREENHEIGHT * BaseRatioSizes[4][3] / 48) / 2;
|
||||
}
|
||||
Displacement = 0;
|
||||
|
@ -1000,7 +1004,7 @@ void DBaseStatusBar::RefreshBackground () const
|
|||
if (x > 0)
|
||||
{
|
||||
y = x == ST_X ? ST_Y : ::ST_Y;
|
||||
x2 = !(ratio & 3) || !Scaled ? ST_X+320 :
|
||||
x2 = !(ratio & 3) || !Scaled ? ST_X+HorizontalResolution :
|
||||
SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2);
|
||||
R_DrawBorder (0, y, x, SCREENHEIGHT);
|
||||
R_DrawBorder (x2, y, SCREENWIDTH, SCREENHEIGHT);
|
||||
|
@ -1500,18 +1504,23 @@ void DBaseStatusBar::BlendView (float blend[4])
|
|||
if (CPlayer->bonuscount)
|
||||
{
|
||||
cnt = CPlayer->bonuscount << 3;
|
||||
AddBlend (0.8431f, 0.7333f, 0.2706f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
|
||||
|
||||
AddBlend (RPART(gameinfo.pickupcolor)/255.f, GPART(gameinfo.pickupcolor)/255.f,
|
||||
BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
|
||||
}
|
||||
|
||||
cnt = DamageToAlpha[MIN (113, CPlayer->damagecount)];
|
||||
|
||||
if (cnt)
|
||||
if (CPlayer->mo->DamageFade.a != 0)
|
||||
{
|
||||
if (cnt > 228)
|
||||
cnt = 228;
|
||||
cnt = DamageToAlpha[MIN (113, CPlayer->damagecount * CPlayer->mo->DamageFade.a / 255)];
|
||||
|
||||
if (cnt)
|
||||
{
|
||||
if (cnt > 228)
|
||||
cnt = 228;
|
||||
|
||||
APlayerPawn *mo = players[consoleplayer].mo;
|
||||
AddBlend (mo->DamageFade.r / 255.f, mo->DamageFade.g / 255.f, mo->DamageFade.b / 255.f, cnt / 255.f, blend);
|
||||
APlayerPawn *mo = CPlayer->mo;
|
||||
AddBlend (mo->DamageFade.r / 255.f, mo->DamageFade.g / 255.f, mo->DamageFade.b / 255.f, cnt / 255.f, blend);
|
||||
}
|
||||
}
|
||||
|
||||
// Unlike Doom, I did not have any utility source to look at to find the
|
||||
|
@ -1591,15 +1600,6 @@ void DBaseStatusBar::FlashItem (const PClass *itemtype)
|
|||
{
|
||||
}
|
||||
|
||||
void DBaseStatusBar::SetFace (void *skn)
|
||||
{
|
||||
}
|
||||
|
||||
void DBaseStatusBar::AddFaceToImageCollection (void *skn, FImageCollection *images)
|
||||
{
|
||||
AddFaceToImageCollectionActual (skn, images, false);
|
||||
}
|
||||
|
||||
void DBaseStatusBar::NewGame ()
|
||||
{
|
||||
}
|
||||
|
@ -1635,72 +1635,6 @@ void DBaseStatusBar::ScreenSizeChanged ()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// AddFaceToImageCollectionActual
|
||||
//
|
||||
// Adds face graphics for specified skin to the specified image collection.
|
||||
// If not in DOOM statusbar and no face in current skin, do NOT default STF*
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::AddFaceToImageCollectionActual (void *skn, FImageCollection *images, bool isDoom)
|
||||
{
|
||||
const char *nameptrs[ST_NUMFACES];
|
||||
char names[ST_NUMFACES][9];
|
||||
char prefix[4];
|
||||
int i, j;
|
||||
int namespc;
|
||||
int facenum;
|
||||
FPlayerSkin *skin = (FPlayerSkin *)skn;
|
||||
|
||||
if ((skin->face[0] == 0) && !isDoom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ST_NUMFACES; i++)
|
||||
{
|
||||
nameptrs[i] = names[i];
|
||||
}
|
||||
|
||||
if (skin->face[0] != 0)
|
||||
{
|
||||
prefix[0] = skin->face[0];
|
||||
prefix[1] = skin->face[1];
|
||||
prefix[2] = skin->face[2];
|
||||
prefix[3] = 0;
|
||||
namespc = skin->namespc;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix[0] = 'S';
|
||||
prefix[1] = 'T';
|
||||
prefix[2] = 'F';
|
||||
prefix[3] = 0;
|
||||
namespc = ns_global;
|
||||
}
|
||||
|
||||
facenum = 0;
|
||||
|
||||
for (i = 0; i < ST_NUMPAINFACES; i++)
|
||||
{
|
||||
for (j = 0; j < ST_NUMSTRAIGHTFACES; j++)
|
||||
{
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sST%d%d", prefix, i, j);
|
||||
}
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sTR%d0", prefix, i); // turn right
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sTL%d0", prefix, i); // turn left
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sOUCH%d", prefix, i); // ouch!
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sEVL%d", prefix, i); // evil grin ;)
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sKILL%d", prefix, i); // pissed off
|
||||
}
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sGOD0", prefix);
|
||||
mysnprintf (names[facenum++], countof(names[0]), "%sDEAD0", prefix);
|
||||
|
||||
images->Add (nameptrs, ST_NUMFACES, namespc);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ValidateInvFirst
|
||||
|
|
|
@ -35,12 +35,14 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include "doomstat.h"
|
||||
#include "d_player.h"
|
||||
#include "g_level.h"
|
||||
#include "g_game.h"
|
||||
#include "gi.h"
|
||||
#include "templates.h"
|
||||
#include "v_font.h"
|
||||
#include "m_fixed.h"
|
||||
#include "gstrings.h"
|
||||
|
||||
TArray<FSkillInfo> AllSkills;
|
||||
int DefaultSkill = -1;
|
||||
|
@ -70,7 +72,6 @@ void FMapInfoParser::ParseSkill ()
|
|||
skill.Aggressiveness = FRACUNIT;
|
||||
skill.SpawnFilter = 0;
|
||||
skill.ACSReturn = 0;
|
||||
skill.MenuNameIsLump = false;
|
||||
skill.MustConfirm = false;
|
||||
skill.Shortcut = 0;
|
||||
skill.TextColor = "";
|
||||
|
@ -79,6 +80,7 @@ void FMapInfoParser::ParseSkill ()
|
|||
skill.MonsterHealth = FRACUNIT;
|
||||
skill.FriendlyHealth = FRACUNIT;
|
||||
skill.NoPain = false;
|
||||
skill.ArmorFactor = FRACUNIT;
|
||||
|
||||
sc.MustGetString();
|
||||
skill.Name = sc.String;
|
||||
|
@ -185,7 +187,6 @@ void FMapInfoParser::ParseSkill ()
|
|||
ParseAssign();
|
||||
sc.MustGetString ();
|
||||
skill.MenuName = sc.String;
|
||||
skill.MenuNameIsLump = false;
|
||||
}
|
||||
else if (sc.Compare("PlayerClassName"))
|
||||
{
|
||||
|
@ -200,8 +201,7 @@ void FMapInfoParser::ParseSkill ()
|
|||
{
|
||||
ParseAssign();
|
||||
sc.MustGetString ();
|
||||
skill.MenuName = sc.String;
|
||||
skill.MenuNameIsLump = true;
|
||||
skill.PicName = sc.String;
|
||||
}
|
||||
else if (sc.Compare("MustConfirm"))
|
||||
{
|
||||
|
@ -250,6 +250,12 @@ void FMapInfoParser::ParseSkill ()
|
|||
{
|
||||
skill.NoPain = true;
|
||||
}
|
||||
else if (sc.Compare("ArmorFactor"))
|
||||
{
|
||||
ParseAssign();
|
||||
sc.MustGetFloat();
|
||||
skill.ArmorFactor = FLOAT2FIXED(sc.Float);
|
||||
}
|
||||
else if (sc.Compare("DefaultSkill"))
|
||||
{
|
||||
if (DefaultSkill >= 0)
|
||||
|
@ -358,12 +364,38 @@ int G_SkillProperty(ESkillProperty prop)
|
|||
return AllSkills[gameskill].FriendlyHealth;
|
||||
|
||||
case SKILLP_NoPain:
|
||||
return AllSkills[gameskill].NoPain;
|
||||
return AllSkills[gameskill].NoPain;
|
||||
|
||||
case SKILLP_ArmorFactor:
|
||||
return AllSkills[gameskill].ArmorFactor;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const char * G_SkillName()
|
||||
{
|
||||
const char *name = AllSkills[gameskill].MenuName;
|
||||
|
||||
player_t *player = &players[consoleplayer];
|
||||
const char *playerclass = player->mo->GetClass()->DisplayName;
|
||||
|
||||
if (playerclass != NULL)
|
||||
{
|
||||
FString * pmnm = AllSkills[gameskill].MenuNamesForPlayerClass.CheckKey(playerclass);
|
||||
if (pmnm != NULL) name = *pmnm;
|
||||
}
|
||||
|
||||
if (*name == '$') name = GStrings(name+1);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -402,8 +434,8 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
|
|||
SpawnFilter = other.SpawnFilter;
|
||||
ACSReturn = other.ACSReturn;
|
||||
MenuName = other.MenuName;
|
||||
PicName = other.PicName;
|
||||
MenuNamesForPlayerClass = other.MenuNamesForPlayerClass;
|
||||
MenuNameIsLump = other.MenuNameIsLump;
|
||||
MustConfirm = other.MustConfirm;
|
||||
MustConfirmText = other.MustConfirmText;
|
||||
Shortcut = other.Shortcut;
|
||||
|
@ -413,6 +445,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
|
|||
MonsterHealth = other.MonsterHealth;
|
||||
FriendlyHealth = other.FriendlyHealth;
|
||||
NoPain = other.NoPain;
|
||||
ArmorFactor = other.ArmorFactor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath)
|
|||
int log;
|
||||
int i;
|
||||
|
||||
CALL_ACTION(A_NoBlocking, self); // [RH] Need this for Sigil rewarding
|
||||
A_Unblock(self, true); // [RH] Need this for Sigil rewarding
|
||||
if (!CheckBossDeath (self))
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger)
|
|||
|
||||
angle = self->angle + (pr_jabdagger.Random2() << 18);
|
||||
pitch = P_AimLineAttack (self, angle, 80*FRACUNIT, &linetarget);
|
||||
P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true);
|
||||
P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true, &linetarget);
|
||||
|
||||
// turn to face target
|
||||
if (linetarget)
|
||||
|
|
|
@ -399,29 +399,38 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
|
|||
ReadCVars (0);
|
||||
}
|
||||
|
||||
strncpy (subsection, "Bindings", sublen);
|
||||
if (!SetSection (section))
|
||||
{ // Config has no bindings for the given game
|
||||
if (!bMigrating)
|
||||
{
|
||||
C_SetDefaultBindings ();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!bMigrating)
|
||||
{
|
||||
C_UnbindAll ();
|
||||
C_SetDefaultBindings ();
|
||||
}
|
||||
|
||||
strncpy (subsection, "Bindings", sublen);
|
||||
if (SetSection (section))
|
||||
{
|
||||
Bindings.UnbindAll();
|
||||
while (NextInSection (key, value))
|
||||
{
|
||||
C_DoBind (key, value, false);
|
||||
Bindings.DoBind (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
strncpy (subsection, "DoubleBindings", sublen);
|
||||
if (SetSection (section))
|
||||
{
|
||||
DoubleBindings.UnbindAll();
|
||||
while (NextInSection (key, value))
|
||||
{
|
||||
C_DoBind (key, value, true);
|
||||
DoubleBindings.DoBind (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
strncpy (subsection, "AutomapBindings", sublen);
|
||||
if (SetSection (section))
|
||||
{
|
||||
AutomapBindings.UnbindAll();
|
||||
while (NextInSection (key, value))
|
||||
{
|
||||
AutomapBindings.DoBind (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,11 +521,15 @@ void FGameConfigFile::ArchiveGameData (const char *gamename)
|
|||
|
||||
strcpy (subsection, "Bindings");
|
||||
SetSection (section, true);
|
||||
C_ArchiveBindings (this, false);
|
||||
Bindings.ArchiveBindings (this);
|
||||
|
||||
strncpy (subsection, "DoubleBindings", sublen);
|
||||
SetSection (section, true);
|
||||
C_ArchiveBindings (this, true);
|
||||
DoubleBindings.ArchiveBindings (this);
|
||||
|
||||
strncpy (subsection, "AutomapBindings", sublen);
|
||||
SetSection (section, true);
|
||||
AutomapBindings.ArchiveBindings (this);
|
||||
}
|
||||
|
||||
void FGameConfigFile::ArchiveGlobalData ()
|
||||
|
|
|
@ -266,6 +266,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_INT(defKickback, "defKickback")
|
||||
GAMEINFOKEY_CSTRING(SkyFlatName, "SkyFlatName", 8)
|
||||
GAMEINFOKEY_STRING(translator, "translator")
|
||||
GAMEINFOKEY_COLOR(pickupcolor, "pickupcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
|
||||
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
|
||||
|
|
4
src/gi.h
4
src/gi.h
|
@ -43,6 +43,9 @@
|
|||
#define GI_MENUHACK_EXTENDED 0x00000004 // (Heretic)
|
||||
#define GI_TEASER2 0x00000008 // Alternate version of the Strife Teaser
|
||||
#define GI_COMPATSHORTTEX 0x00000010 // always force COMPAT_SHORTTEX for IWAD maps.
|
||||
#define GI_COMPATSTAIRS 0x00000020 // same for stairbuilding
|
||||
#define GI_COMPATPOLY1 0x00000040 // Hexen's MAP36 needs old polyobject drawing
|
||||
#define GI_COMPATPOLY2 0x00000080 // so does HEXDD's MAP47
|
||||
|
||||
#include "gametype.h"
|
||||
|
||||
|
@ -105,6 +108,7 @@ struct gameinfo_t
|
|||
int defaultrespawntime;
|
||||
int defaultdropstyle;
|
||||
int player5start;
|
||||
DWORD pickupcolor;
|
||||
|
||||
const char *GetFinalePage(unsigned int num) const;
|
||||
};
|
||||
|
|
|
@ -269,8 +269,16 @@ void PacketGet (void)
|
|||
if (err == WSAECONNRESET)
|
||||
{ // The remote node aborted unexpectedly, so pretend it sent an exit packet
|
||||
|
||||
StartScreen->NetMessage ("The connection from %s was dropped.\n",
|
||||
players[sendplayer[node]].userinfo.netname);
|
||||
if (StartScreen != NULL)
|
||||
{
|
||||
StartScreen->NetMessage ("The connection from %s was dropped.\n",
|
||||
players[sendplayer[node]].userinfo.netname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("The connection from %s was dropped.\n",
|
||||
players[sendplayer[node]].userinfo.netname);
|
||||
}
|
||||
|
||||
doomcom.data[0] = 0x80; // NCMD_EXIT
|
||||
c = 1;
|
||||
|
|
|
@ -134,6 +134,10 @@ void PClassActor::StaticInit()
|
|||
// Sprite 1 is always ----
|
||||
memcpy (temp.name, "----", 5);
|
||||
sprites.Push (temp);
|
||||
|
||||
// Sprite 2 is always ####
|
||||
memcpy (temp.name, "####", 5);
|
||||
sprites.Push (temp);
|
||||
}
|
||||
|
||||
Printf ("LoadActors: Load actor definitions.\n");
|
||||
|
@ -625,7 +629,6 @@ CCMD (dumpmapthings)
|
|||
FDoomEdMap::DumpMapThings ();
|
||||
}
|
||||
|
||||
bool CheckCheatmode ();
|
||||
|
||||
static void SummonActor (int command, int command2, FCommandLine argv)
|
||||
{
|
||||
|
|
29
src/info.h
29
src/info.h
|
@ -46,20 +46,28 @@
|
|||
#include "vm.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
const BYTE SF_FULLBRIGHT = 0x40;
|
||||
|
||||
struct Baggage;
|
||||
class FScanner;
|
||||
struct FActorInfo;
|
||||
class FArchive;
|
||||
|
||||
// Sprites that are fixed in position because they can have special meanings.
|
||||
enum
|
||||
{
|
||||
SPR_TNT1, // The empty sprite
|
||||
SPR_FIXED, // Do not change sprite or frame
|
||||
SPR_NOCHANGE, // Do not change sprite (frame change is okay)
|
||||
};
|
||||
|
||||
struct FState
|
||||
{
|
||||
WORD sprite;
|
||||
SWORD Tics;
|
||||
long Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
long Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
BYTE Frame;
|
||||
int Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
int Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
BYTE Frame:6;
|
||||
BYTE Fullbright:1; // State is fullbright
|
||||
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
||||
BYTE DefineFlags; // Unused byte so let's use it during state creation.
|
||||
short Light;
|
||||
FState *NextState;
|
||||
|
@ -67,11 +75,15 @@ struct FState
|
|||
|
||||
inline int GetFrame() const
|
||||
{
|
||||
return Frame & ~(SF_FULLBRIGHT);
|
||||
return Frame;
|
||||
}
|
||||
inline bool GetSameFrame() const
|
||||
{
|
||||
return SameFrame;
|
||||
}
|
||||
inline int GetFullbright() const
|
||||
{
|
||||
return Frame & SF_FULLBRIGHT ? 0x10 /*RF_FULLBRIGHT*/ : 0;
|
||||
return Fullbright ? 0x10 /*RF_FULLBRIGHT*/ : 0;
|
||||
}
|
||||
inline int GetTics() const
|
||||
{
|
||||
|
@ -91,7 +103,7 @@ struct FState
|
|||
}
|
||||
inline void SetFrame(BYTE frame)
|
||||
{
|
||||
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A');
|
||||
Frame = frame - 'A';
|
||||
}
|
||||
void SetAction(VMFunction *func) { ActionFunc = func; }
|
||||
bool CallAction(AActor *self, AActor *stateowner, StateCallData *statecall = NULL);
|
||||
|
@ -185,6 +197,7 @@ public:
|
|||
FName BloodType3; // AxeBlood replacement type
|
||||
|
||||
DDropItem *DropItems;
|
||||
FString SourceLumpName;
|
||||
|
||||
// Old Decorate compatibility stuff
|
||||
bool DontHurtShooter;
|
||||
|
|
|
@ -302,6 +302,19 @@ void DArgs::AppendArgs(int argc, const FString *argv)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DArgs :: RemoveArg
|
||||
//
|
||||
// Removes a single argument from argv.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void DArgs::RemoveArg(int argindex)
|
||||
{
|
||||
Argv.Delete(argindex);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DArgs :: CollectFiles
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
|
||||
void AppendArg(FString arg);
|
||||
void AppendArgs(int argc, const FString *argv);
|
||||
void RemoveArg(int argindex);
|
||||
void SetArgs(int argc, char **argv);
|
||||
void CollectFiles(const char *param, const char *extension);
|
||||
DArgs *GatherFiles(const char *param) const;
|
||||
|
|
|
@ -91,8 +91,3 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
|
|||
return (p1 == p2) ? p1 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "doomtype.h"
|
||||
|
||||
struct line_t;
|
||||
struct node_t;
|
||||
|
||||
class FBoundingBox
|
||||
{
|
||||
|
|
|
@ -601,7 +601,7 @@ void GiveSpawner (player_t *player, PClassInventory *type, int amount)
|
|||
|
||||
void cht_Give (player_t *player, const char *name, int amount)
|
||||
{
|
||||
bool giveall;
|
||||
enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
|
||||
int i;
|
||||
PClassActor *type;
|
||||
|
||||
|
@ -613,9 +613,17 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
return;
|
||||
}
|
||||
|
||||
giveall = (stricmp (name, "all") == 0);
|
||||
giveall = ALL_NO;
|
||||
if (stricmp (name, "all") == 0)
|
||||
{
|
||||
giveall = ALL_YES;
|
||||
}
|
||||
else if (stricmp (name, "everything") == 0)
|
||||
{
|
||||
giveall = ALL_YESYES;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "health") == 0)
|
||||
if (stricmp (name, "health") == 0)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
|
@ -640,9 +648,6 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
player->health = deh.GodHealth;
|
||||
}
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "backpack") == 0)
|
||||
|
@ -757,7 +762,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
player->weapons.LocateWeapon(static_cast<PClassWeapon *>(type), NULL, NULL))
|
||||
{
|
||||
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
||||
if (!(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
||||
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
||||
{
|
||||
GiveSpawner (player, static_cast<PClassInventory *>(type), 1);
|
||||
}
|
||||
|
@ -783,7 +788,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
!type->IsDescendantOf (RUNTIME_CLASS(APowerup)) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS(AArmor)))
|
||||
{
|
||||
GiveSpawner (player, static_cast<PClassInventory *>(type), 1);
|
||||
GiveSpawner (player, static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -801,7 +806,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
AInventory *def = (AInventory*)GetDefaultByType (type);
|
||||
if (def->Icon.isValid())
|
||||
{
|
||||
GiveSpawner (player, static_cast<PClassInventory *>(type), 1);
|
||||
GiveSpawner (player, static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1063,7 +1068,6 @@ void cht_Suicide (player_t *plyr)
|
|||
}
|
||||
}
|
||||
|
||||
bool CheckCheatmode ();
|
||||
|
||||
CCMD (mdk)
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue