# Conflicts:
#	src/CMakeLists.txt
#	src/basicinlines.h
#	src/m_fixed.h
#	src/r_3dfloors.h
#	src/r_bsp.cpp
#	src/r_bsp.h
#	src/r_draw.cpp
#	src/r_draw.h
#	src/r_main.cpp
#	src/r_main.h
#	src/r_plane.h
#	src/r_segs.h
#	src/r_swrenderer.cpp
#	src/r_things.cpp
#	src/r_things.h
#	src/win32/fb_d3d9.cpp
#	src/win32/fb_ddraw.cpp
#	wadsrc_lights/static/doomdefs.txt
#	wadsrc_lights/static/hticdefs.txt
This commit is contained in:
nashmuhandes 2016-12-23 00:51:30 +08:00
commit e5e7e85b81
805 changed files with 83417 additions and 61653 deletions

View file

@ -2,8 +2,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
@ -317,3 +317,11 @@ Fixes some minor bugs since the last version, 1.0.3.
~~~~~~~~~~~~~~~~~
Security fix only. Fixes CERT-FI 20469 as it applies to bzip2.
1.0.6 (6 Sept 10)
~~~~~~~~~~~~~~~~~
* Security fix for CVE-2010-0405. This was reported by Mikolaj
Izdebski.
* Make the documentation build on Ubuntu 10.04

View file

@ -2,7 +2,7 @@
--------------------------------------------------------------------------
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2007 Julian R Seward. All
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
@ -37,6 +37,6 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.5 of 10 December 2007
bzip2/libbzip2 version 1.0.6 of 6 September 2010
--------------------------------------------------------------------------

View file

@ -6,8 +6,8 @@ This version is fully compatible with the previous public releases.
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
@ -181,6 +181,10 @@ WHAT'S NEW IN 1.0.5 ?
See the CHANGES file.
WHAT'S NEW IN 1.0.6 ?
See the CHANGES file.
I hope you find bzip2 useful. Feel free to contact me at
jseward@bzip.org
@ -208,3 +212,4 @@ Cambridge, UK.
15 February 2005 (bzip2, version 1.0.3)
20 December 2006 (bzip2, version 1.0.4)
10 December 2007 (bzip2, version 1.0.5)
6 Sept 2010 (bzip2, version 1.0.6)

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
@ -36,7 +36,7 @@
/*-- General stuff. --*/
#define BZ_VERSION "1.0.5, 10-Dec-2007"
#define BZ_VERSION "1.0.6, 6-Sept-2010"
typedef char Char;
typedef unsigned char Bool;

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
@ -381,6 +381,13 @@ Int32 BZ2_decompress ( DState* s )
es = -1;
N = 1;
do {
/* Check that N doesn't get too big, so that es doesn't
go negative. The maximum value that can be
RUNA/RUNB encoded is equal to the block size (post
the initial RLE), viz, 900k, so bounding N at 2
million should guard against overflow without
rejecting any legitimate inputs. */
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
N = N * 2;
@ -485,15 +492,28 @@ Int32 BZ2_decompress ( DState* s )
RETURN(BZ_DATA_ERROR);
/*-- Set up cftab to facilitate generation of T^(-1) --*/
/* Check: unzftab entries in range. */
for (i = 0; i <= 255; i++) {
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
RETURN(BZ_DATA_ERROR);
}
/* Actually generate cftab. */
s->cftab[0] = 0;
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
/* Check: cftab entries in range. */
for (i = 0; i <= 256; i++) {
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
/* s->cftab[i] can legitimately be == nblock */
RETURN(BZ_DATA_ERROR);
}
}
/* Check: cftab entries non-descending. */
for (i = 1; i <= 256; i++) {
if (s->cftab[i-1] > s->cftab[i]) {
RETURN(BZ_DATA_ERROR);
}
}
s->state_out_len = 0;
s->state_out_ch = 0;

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -8,8 +8,8 @@
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.

View file

@ -4,7 +4,7 @@ project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
set(GME_VERSION 0.6.1 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop
@ -79,6 +79,9 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ZD_FASTMATH_FLAG}" )
SET(USE_GME_NSF 1 BOOL "Enable NES NSF music emulation")
#endif()
# [ZDoom] Set always to OFF.
set(BUILD_SHARED_LIBS OFF)
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
@ -101,10 +104,17 @@ if (CMAKE_COMPILER_IS_GNUCXX)
endif()
endif()
endif() # test visibility
endif()
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif()
# Shared library defined here
add_subdirectory(gme)
# EXCLUDE_FROM_ALL adds build rules but keeps it out of default build
# [ZDoom] Not needed.
if( FALSE )
add_subdirectory(player EXCLUDE_FROM_ALL)
add_subdirectory(demo EXCLUDE_FROM_ALL)
endif()

View file

@ -1,6 +1,18 @@
Game_Music_Emu Change Log
-------------------------
Game_Music_Emu 0.6.1
--------------------
- Moved repository to Bitbucket since Google Code announced they would
shutdown this year.
- Packaging improvements:
- Honor $LIB_SUFFIX for installed pkg-config metadata.
- Support setting BUILD_SHARED_LIBS to OFF to build libgme as a static
library. (Pass -DBUILD_SHARED_LIBS=OFF when running cmake).
Thanks to lachs0r.
Game_Music_Emu 0.6.0
--------------------

View file

@ -1,10 +1,11 @@
Game_Music_Emu 0.6.0
Game_Music_Emu 0.6.1
--------------------
Author : Shay Green <gblargg@gmail.com>
Website: http://www.slack.net/~ant/libs/
Forum : http://groups.google.com/group/blargg-sound-libs
Source : https://code.google.com/p/game-music-emu/
License: GNU Lesser General Public License (LGPL)
Author : Shay Green <gblargg@gmail.com>
Maintainer : Michael Pyne <mpyne@purinchu.net>
Website : http://www.slack.net/~ant/libs/
Forum : http://groups.google.com/group/blargg-sound-libs
Source : https://bitbucket.org/mpyne/game-music-emu/
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents
--------

View file

@ -131,6 +131,12 @@ set (EXPORTED_HEADERS gme.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gme_types.h.in
${CMAKE_CURRENT_BINARY_DIR}/gme_types.h)
# [ZDoom] Not needed.
if( FALSE )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libgme.pc.in
${CMAKE_CURRENT_BINARY_DIR}/libgme.pc @ONLY)
endif()
# On some platforms we may need to change headers or whatnot based on whether
# we're building the library or merely using the library. The following is
# only defined when building the library to allow us to tell which is which.
@ -147,7 +153,18 @@ add_library(gme ${libgme_SRCS})
# to the API), the SOVERSION should be the same even when bumping up VERSION.
# The way gme.h is designed, SOVERSION should very rarely be bumped, if ever.
# Hopefully the API can stay compatible with old versions.
#set_target_properties(gme
# PROPERTIES VERSION ${GME_VERSION}
# SOVERSION 0)
# [ZDoom] Not needed.
if( FALSE )
set_target_properties(gme
PROPERTIES VERSION ${GME_VERSION}
SOVERSION 0)
install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
RUNTIME DESTINATION bin # DLL platforms
ARCHIVE DESTINATION lib) # DLL platforms
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)
endif()
target_link_libraries(gme)

View file

@ -129,6 +129,8 @@ private:
};
#ifdef HAVE_ZLIB_H
#include <zlib.h>
// Gzip compressed file reader
class Gzip_File_Reader : public File_Reader {
public:
@ -143,7 +145,7 @@ public:
long tell() const;
blargg_err_t seek( long );
private:
void* file_;
gzFile file_;
long size_;
};
#endif

View file

@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
}
long Music_Emu::tell_samples() const
{
return out_time;
}
long Music_Emu::tell() const
{
blargg_long rate = sample_rate() * stereo;
@ -185,14 +190,18 @@ long Music_Emu::tell() const
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
}
blargg_err_t Music_Emu::seek( long msec )
blargg_err_t Music_Emu::seek_samples( long time )
{
blargg_long time = msec_to_samples( msec );
if ( time < out_time )
RETURN_ERR( start_track( current_track_ ) );
return skip( time - out_time );
}
blargg_err_t Music_Emu::seek( long msec )
{
return seek_samples( msec_to_samples( msec ) );
}
blargg_err_t Music_Emu::skip( long count )
{
require( current_track() >= 0 ); // start_track() must have been called already

View file

@ -41,9 +41,15 @@ public:
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
long tell() const;
// Number of samples generated since beginning of track
long tell_samples() const;
// Seek to new time in track. Seeking backwards or far forward can take a while.
blargg_err_t seek( long msec );
// Equivalent to restarting track then skipping n samples
blargg_err_t seek_samples( long n );
// Skip n samples
blargg_err_t skip( long n );

View file

@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
#endif
// Registers other than $F2 and $F4-$F7
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
// TODO: this is a bit on the fragile side
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
cpu_write_smp_reg( data, time, reg );
}
// High mem/address wrap-around

View file

@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// TODO: remove non-wrapping versions?
#define SPC_NO_SP_WRAPAROUND 0
#define SET_SP( v ) (sp = ram + 0x101 + (v))
#define GET_SP() (int(sp - 0x101 - ram))
#define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
#define GET_SP() (uint8_t (sp - 0x101 - ram))
#if SPC_NO_SP_WRAPAROUND
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
@ -485,7 +485,7 @@ loop:
case 0xAF: // MOV (X)+,A
WRITE_DP( 0, x, a + no_read_before_write );
x++;
x = (uint8_t) (x + 1);
goto loop;
// 5. 8-BIT LOGIC OPERATION COMMANDS
@ -808,7 +808,7 @@ loop:
unsigned temp = y * a;
a = (uint8_t) temp;
nz = ((temp >> 1) | temp) & 0x7F;
y = temp >> 8;
y = (uint8_t) (temp >> 8);
nz |= y;
goto loop;
}
@ -838,6 +838,7 @@ loop:
nz = (uint8_t) a;
a = (uint8_t) a;
y = (uint8_t) y;
goto loop;
}
@ -1004,7 +1005,7 @@ loop:
case 0x7F: // RET1
temp = *sp;
SET_PC( GET_LE16( sp + 1 ) );
sp += 3;
SET_SP(GET_SP() + 3);
goto set_psw;
case 0x8E: // POP PSW
POP( temp );

View file

@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }

View file

@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.0 */
/* Game_Music_Emu 0.6.1 */
#ifndef GME_H
#define GME_H
@ -8,7 +8,7 @@
extern "C" {
#endif
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/

View file

@ -1,4 +1,4 @@
Game_Music_Emu 0.6.0: Game Music Emulators
Game_Music_Emu 0.6.1: Game Music Emulators
------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems:
@ -38,26 +38,42 @@ Website: http://www.slack.net/~ant/
Forum : http://groups.google.com/group/blargg-sound-libs
License: GNU Lesser General Public License (LGPL)
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
Getting Started
---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
all source files in gme/. If you have CMake 2.6 or later, execute
all source files in gme/.
run cmake
cd demo
run make
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
extracted source directory):
Be sure "test.nsf" is in the same directory as the program. Running it
mkdir build
cd build
cmake ../ # <-- Pass any needed CMake flags here
make # To build the library
cd demo
make # To build the demo itself
Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav".
You can use "make install" to install the library. To choose where to install
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
(and replace /usr/local with the base path you wish to use). Alternately, you
can specify the base path to install to when you run "make install" by passing
'DESTDIR=/usr/local' on the make install command line (again, replace
/usr/local as appropriate).
To build a static library instead of shared (the default), pass
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
A slightly more extensive demo application is available in the player/
directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for
assistance.
Files
-----
gme.txt General notes about the library

View file

@ -252,9 +252,10 @@ Note: All <bool> fields default to false unless mentioned otherwise.
// negative values are used as their absolute. Default = 1.
renderstyle = <string>; // Set per-actor render style, overriding the class default. Possible values can be "normal",
// "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil",
// "translucent", "fuzzy", "optfuzzy", "soultrans". Default is an empty string for no change.
fillcolor = <integer>; // Fill color used by the "stencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000.
// "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil",
// "addstencil", "shaded", "addshaded", "translucent", "fuzzy", "optfuzzy", "soultrans" and "shadow".
// Default is an empty string for no change.
fillcolor = <integer>; // Fill color used by the "stencil", "addstencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000.
alpha = <float>; // Translucency of this actor (if applicable to renderstyle), default is 1.0.
score = <int>; // Score value of this actor, overriding the class default if not null. Default = 0.
pitch = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).

View file

@ -47,9 +47,9 @@ if( WIN32 )
set( WIN_TYPE Win32 )
set( XBITS x86 )
endif()
add_definitions( -D_WIN32 )
find_path( D3D_INCLUDE_DIR d3d9.h
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include )
@ -64,7 +64,7 @@ if( WIN32 )
else()
include_directories( ${D3D_INCLUDE_DIR} )
endif()
find_path( XINPUT_INCLUDE_DIR xinput.h
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include )
@ -134,7 +134,6 @@ else()
else()
option( NO_GTK "Disable GTK+ dialogs (Not applicable to Windows)" )
option( DYN_GTK "Load GTK+ at runtime instead of compile time" ON )
option( VALGRIND "Add special Valgrind sequences to self-modifying code" )
# Use GTK+ for the IWAD picker, if available.
if( NOT NO_GTK )
@ -159,7 +158,7 @@ else()
endif()
endif()
endif()
if( NO_GTK )
add_definitions( -DNO_GTK )
elseif( DYN_GTK )
@ -498,7 +497,7 @@ if( WIN32 )
set( SYSTEM_SOURCES_DIR win32 )
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} ${PLAT_UNIX_SOURCES} )
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} win32/zdoom.rc )
elseif( APPLE )
if( OSX_COCOA_BACKEND )
@ -540,16 +539,13 @@ if( HAVE_MMX )
PROPERTIES COMPILE_FLAGS "-mmmx" )
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
endif( HAVE_MMX )
add_definitions( -DNOASM )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h
COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h
COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/zscript/zcc-parse.lemon
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/zscript/zcc-parse.lemon )
COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/zcc-parse.lemon
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/zcc-parse.lemon )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h
COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re
@ -597,11 +593,8 @@ endif()
file( GLOB HEADER_FILES
${EXTRA_HEADER_DIRS}
fragglescript/*.h
g_doom/*.h
g_heretic/*.h
g_hexen/*.h
g_raven/*.h
g_shared/*.h
g_inventory/*.h
g_strife/*.h
intermission/*.h
menu/*.h
@ -609,13 +602,17 @@ file( GLOB HEADER_FILES
posix/cocoa/*.h
posix/sdl/*.h
r_data/*.h
rapidjson/*.h
resourcefiles/*.h
sfmt/*.h
sound/*.h
textures/*.h
thingdef/*.h
scripting/*.h
scripting/codegeneration/*.h
scripting/decorate/*.h
scripting/zscript/*.h
scripting/vm/*.h
xlat/*.h
zscript/*.h
gl/*.h
gl/api/*.h
gl/data/*.h
@ -640,86 +637,11 @@ set( NOT_COMPILED_SOURCE_FILES
${OTHER_SYSTEM_SOURCES}
sc_man_scanner.h
sc_man_scanner.re
g_doom/a_arachnotron.cpp
g_doom/a_archvile.cpp
g_doom/a_bossbrain.cpp
g_doom/a_bruiser.cpp
g_doom/a_cacodemon.cpp
g_doom/a_cyberdemon.cpp
g_doom/a_demon.cpp
g_doom/a_doomimp.cpp
g_doom/a_doomweaps.cpp
g_doom/a_fatso.cpp
g_doom/a_keen.cpp
g_doom/a_lostsoul.cpp
g_doom/a_painelemental.cpp
g_doom/a_possessed.cpp
g_doom/a_revenant.cpp
g_doom/a_scriptedmarine.cpp
g_doom/a_spidermaster.cpp
g_heretic/a_chicken.cpp
g_heretic/a_dsparil.cpp
g_heretic/a_hereticartifacts.cpp
g_heretic/a_hereticimp.cpp
g_heretic/a_hereticweaps.cpp
g_heretic/a_ironlich.cpp
g_heretic/a_knight.cpp
g_heretic/a_wizard.cpp
g_hexen/a_bats.cpp
g_hexen/a_bishop.cpp
g_hexen/a_blastradius.cpp
g_hexen/a_boostarmor.cpp
g_hexen/a_centaur.cpp
g_hexen/a_clericflame.cpp
g_hexen/a_clericholy.cpp
g_hexen/a_clericmace.cpp
g_hexen/a_clericstaff.cpp
g_hexen/a_dragon.cpp
g_hexen/a_fighteraxe.cpp
g_hexen/a_fighterhammer.cpp
g_hexen/a_fighterplayer.cpp
g_hexen/a_fighterquietus.cpp
g_hexen/a_firedemon.cpp
g_hexen/a_flechette.cpp
g_hexen/a_flies.cpp
g_hexen/a_fog.cpp
g_hexen/a_healingradius.cpp
g_hexen/a_heresiarch.cpp
g_hexen/a_hexenspecialdecs.cpp
g_hexen/a_iceguy.cpp
g_hexen/a_korax.cpp
g_hexen/a_magecone.cpp
g_hexen/a_magelightning.cpp
g_hexen/a_magestaff.cpp
g_hexen/a_pig.cpp
g_hexen/a_serpent.cpp
g_hexen/a_spike.cpp
g_hexen/a_summon.cpp
g_hexen/a_teleportother.cpp
g_hexen/a_wraith.cpp
g_strife/a_acolyte.cpp
g_strife/a_alienspectres.cpp
g_strife/a_coin.cpp
g_strife/a_crusader.cpp
g_strife/a_entityboss.cpp
g_strife/a_inquisitor.cpp
g_strife/a_loremaster.cpp
g_strife/a_oracle.cpp
g_strife/a_programmer.cpp
g_strife/a_reaver.cpp
g_strife/a_rebels.cpp
g_strife/a_sentinel.cpp
g_strife/a_spectral.cpp
g_strife/a_stalker.cpp
g_strife/a_strifeitems.cpp
g_strife/a_strifeweapons.cpp
g_strife/a_templar.cpp
g_strife/a_thingstoblowup.cpp
g_shared/sbarinfo_commands.cpp
xlat/xlat_parser.y
xlat_parser.c
xlat_parser.h
zscript/zcc-parse.lemon
scripting/zscript/zcc-parse.lemon
zcc-parse.c
zcc-parse.h
)
@ -863,6 +785,7 @@ set( FASTMATH_SOURCES
gl/shaders/gl_presentshader.cpp
gl/shaders/gl_present3dRowshader.cpp
gl/shaders/gl_bloomshader.cpp
gl/shaders/gl_ambientshader.cpp
gl/shaders/gl_blurshader.cpp
gl/shaders/gl_colormapshader.cpp
gl/shaders/gl_tonemapshader.cpp
@ -1018,44 +941,32 @@ set (PCH_SOURCES
w_wad.cpp
wi_stuff.cpp
zstrformat.cpp
g_doom/a_doommisc.cpp
g_heretic/a_hereticmisc.cpp
g_hexen/a_hexenmisc.cpp
g_raven/a_artitele.cpp
g_raven/a_minotaur.cpp
g_strife/a_strifestuff.cpp
g_inventory/a_ammo.cpp
g_inventory/a_armor.cpp
g_inventory/a_artifacts.cpp
g_inventory/a_health.cpp
g_inventory/a_keys.cpp
g_inventory/a_pickups.cpp
g_inventory/a_puzzleitems.cpp
g_inventory/a_weaponpiece.cpp
g_inventory/a_weapons.cpp
g_strife/strife_sbar.cpp
g_shared/a_action.cpp
g_shared/a_armor.cpp
g_shared/a_artifacts.cpp
g_shared/a_bridge.cpp
g_shared/a_camera.cpp
g_shared/a_debris.cpp
g_shared/a_decals.cpp
g_shared/a_fastprojectile.cpp
g_shared/a_flashfader.cpp
g_shared/a_fountain.cpp
g_shared/a_hatetarget.cpp
g_shared/a_keys.cpp
g_shared/a_lightning.cpp
g_shared/a_mapmarker.cpp
g_shared/a_morph.cpp
g_shared/a_movingcamera.cpp
g_shared/a_pickups.cpp
g_shared/a_puzzleitems.cpp
g_shared/a_quake.cpp
g_shared/a_randomspawner.cpp
g_shared/a_secrettrigger.cpp
g_shared/a_sectoraction.cpp
g_shared/a_setcolor.cpp
g_shared/a_skies.cpp
g_shared/a_soundenvironment.cpp
g_shared/a_soundsequence.cpp
g_shared/a_spark.cpp
g_shared/a_specialspot.cpp
g_shared/a_waterzone.cpp
g_shared/a_weaponpiece.cpp
g_shared/a_weapons.cpp
g_shared/hudmessages.cpp
g_shared/sbarinfo.cpp
g_shared/sbar_mugshot.cpp
@ -1091,14 +1002,6 @@ set (PCH_SOURCES
textures/texturemanager.cpp
textures/tgatexture.cpp
textures/warptexture.cpp
thingdef/olddecorations.cpp
thingdef/thingdef.cpp
thingdef/thingdef_data.cpp
thingdef/thingdef_exp.cpp
thingdef/thingdef_expression.cpp
thingdef/thingdef_parse.cpp
thingdef/thingdef_properties.cpp
thingdef/thingdef_states.cpp
xlat/parse_xlat.cpp
fragglescript/t_func.cpp
fragglescript/t_load.cpp
@ -1113,15 +1016,23 @@ set (PCH_SOURCES
r_data/voxels.cpp
r_data/renderstyle.cpp
r_data/r_interpolate.cpp
scripting/thingdef.cpp
scripting/thingdef_data.cpp
scripting/thingdef_properties.cpp
scripting/codegeneration/codegen.cpp
scripting/decorate/olddecorations.cpp
scripting/decorate/thingdef_exp.cpp
scripting/decorate/thingdef_parse.cpp
scripting/decorate/thingdef_states.cpp
scripting/vm/vmbuilder.cpp
scripting/vm/vmdisasm.cpp
scripting/vm/vmexec.cpp
scripting/vm/vmframe.cpp
scripting/zscript/ast.cpp
scripting/zscript/zcc_compile.cpp
scripting/zscript/zcc_expr.cpp
scripting/zscript/zcc_parser.cpp
sfmt/SFMT.cpp
zscript/ast.cpp
zscript/vmbuilder.cpp
zscript/vmdisasm.cpp
zscript/vmexec.cpp
zscript/vmframe.cpp
zscript/zcc_compile.cpp
zscript/zcc_expr.cpp
zscript/zcc_parser.cpp
)
enable_precompiled_headers( g_pch.h PCH_SOURCES )
@ -1146,6 +1057,8 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
math/log10.c
math/mtherr.c
math/polevl.c
math/pow.c
math/powi.c
math/sin.c
math/sinh.c
math/sqrt.c
@ -1171,19 +1084,16 @@ endif()
target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma )
include_directories( .
g_doom
g_heretic
g_hexen
g_raven
g_strife
g_shared
g_inventory
sound
textures
thingdef
timidity
wildmidi
xlat
zscript
scripting
scripting/vm
../gdtoa
../dumb/include
${CMAKE_BINARY_DIR}/gdtoa
@ -1262,17 +1172,14 @@ source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRE
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")
source_group("Audio Files\\WildMidi\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/wildmidi/.+\\.h$")
source_group("Audio Files\\WildMidi\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/wildmidi/.+\\.cpp$")
source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+")
source_group("External\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+")
source_group("External\\RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/.+")
source_group("Externak\\SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+")
source_group("Games\\Heretic Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_heretic/.+")
source_group("Games\\Hexen Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_hexen/.+")
source_group("Games\\Raven Shared" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_raven/.+")
source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_strife/.+")
source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+")
source_group("Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+")
source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+")
source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+")
source_group("RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/.+")
source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+")
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")
@ -1294,15 +1201,18 @@ source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURREN
source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+")
source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h)
source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+")
source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")
source_group("OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+")
source_group("Unix Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/unix/.+")
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
source_group("Platforms\\POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
source_group("Platforms\\Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")
source_group("Platforms\\OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+")
source_group("Platforms\\Unix Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/unix/.+")
source_group("Platforms\\SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
source_group("Platforms\\Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+")
source_group("Scripting\\Decorate" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/decorate/.+")
source_group("Scripting\\ZScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
source_group("Scripting\\Code Generation" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/codegeneration/.+")
source_group("Scripting\\VM" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/vm/.+")
source_group("Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/.+")
source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+")
source_group("Versioning" FILES version.h win32/zdoom.rc)
source_group("Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+")
source_group("Xlat" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/xlat/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h)
source_group("ZScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/zscript/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
source_group("Source Files" FILES ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h sc_man_scanner.re)

View file

@ -52,8 +52,8 @@
// a single section during the final link. (.rdata is the standard section
// for initialized read-only data.)
#pragma comment(linker, "/merge:.areg=.rdata /merge:.creg=.rdata /merge:.greg=.rdata")
#pragma comment(linker, "/merge:.yreg=.rdata")
#pragma comment(linker, "/merge:.areg=.rdata /merge:.creg=.rdata /merge:.freg=.rdata")
#pragma comment(linker, "/merge:.greg=.rdata /merge:.yreg=.rdata")
#pragma section(".areg$a",read)
__declspec(allocate(".areg$a")) void *const ARegHead = 0;
@ -61,6 +61,9 @@ __declspec(allocate(".areg$a")) void *const ARegHead = 0;
#pragma section(".creg$a",read)
__declspec(allocate(".creg$a")) void *const CRegHead = 0;
#pragma section(".freg$a",read)
__declspec(allocate(".freg$a")) void *const FRegHead = 0;
#pragma section(".greg$a",read)
__declspec(allocate(".greg$a")) void *const GRegHead = 0;
@ -97,6 +100,7 @@ __declspec(allocate(".yreg$a")) void *const YRegHead = 0;
void *const ARegHead __attribute__((section(SECTION_AREG))) = 0;
void *const CRegHead __attribute__((section(SECTION_CREG))) = 0;
void *const FRegHead __attribute__((section(SECTION_FREG))) = 0;
void *const GRegHead __attribute__((section(SECTION_GREG))) = 0;
void *const YRegHead __attribute__((section(SECTION_YREG))) = 0;

View file

@ -386,6 +386,8 @@ enum ActorFlag7
MF7_USEKILLSCRIPTS = 0x00800000, // [JM] Use "KILL" Script on death if not forced by GameInfo.
MF7_NOKILLSCRIPTS = 0x01000000, // [JM] No "KILL" Script on death whatsoever, even if forced by GameInfo.
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
MF7_SMASHABLE = 0x04000000, // dies if hitting the floor.
MF7_NOSHIELDREFLECT = 0x08000000, // will not be reflected by shields.
};
// --- mobj.renderflags ---
@ -584,11 +586,13 @@ public:
AActor () throw();
AActor (const AActor &other) throw();
AActor &operator= (const AActor &other);
void Destroy ();
~AActor ();
void Serialize(FSerializer &arc);
void PostSerialize();
virtual void Destroy() override;
virtual void Serialize(FSerializer &arc) override;
virtual void PostSerialize() override;
virtual void PostBeginPlay() override; // Called immediately before the actor's first tick
virtual void Tick() override;
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
@ -612,43 +616,50 @@ public:
bool CheckNoDelay();
virtual void BeginPlay(); // Called immediately after the actor is created
virtual void PostBeginPlay(); // Called immediately before the actor's first tick
virtual void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world
void CallBeginPlay();
void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world
virtual void HandleSpawnFlags(); // Translates SpawnFlags into in-game flags.
virtual void MarkPrecacheSounds() const; // Marks sounds used by this actor for precaching.
virtual void Activate (AActor *activator);
virtual void Deactivate (AActor *activator);
void CallActivate(AActor *activator);
virtual void Tick ();
virtual void Deactivate(AActor *activator);
void CallDeactivate(AActor *activator);
// Called when actor dies
virtual void Die (AActor *source, AActor *inflictor, int dmgflags = 0);
void CallDie(AActor *source, AActor *inflictor, int dmgflags = 0);
// Perform some special damage action. Returns the amount of damage to do.
// Returning -1 signals the damage routine to exit immediately
virtual int DoSpecialDamage (AActor *target, int damage, FName damagetype);
int CallDoSpecialDamage(AActor *target, int damage, FName damagetype);
// Like DoSpecialDamage, but called on the actor receiving the damage.
virtual int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
int CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype);
// Actor had MF_SKULLFLY set and rammed into something
// Returns false to stop moving and true to keep moving
virtual bool Slam(AActor *victim);
bool CallSlam(AActor *victim);
// Something just touched this actor.
virtual void Touch(AActor *toucher);
void CallTouch(AActor *toucher);
// Centaurs and ettins squeal when electrocuted, poisoned, or "holy"-ed
// Made a metadata property so no longer virtual
void Howl ();
// Actor just hit the floor
virtual void HitFloor ();
// plays bouncing sound
void PlayBounceSound(bool onfloor);
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
virtual bool FloorBounceMissile (secplane_t &plane);
// Called when an actor is to be reflected by a disc of repulsion.
// Returns true to continue normal blast processing.
virtual bool SpecialBlastHandling (AActor *source, double strength);
bool FloorBounceMissile (secplane_t &plane);
// Called by RoughBlockCheck
bool IsOkayToAttack (AActor *target);
@ -656,27 +667,28 @@ public:
// Plays the actor's ActiveSound if its voice isn't already making noise.
void PlayActiveSound ();
// Actor had MF_SKULLFLY set and rammed into something
// Returns false to stop moving and true to keep moving
virtual bool Slam (AActor *victim);
void RestoreSpecialPosition();
// Called by PIT_CheckThing() and needed for some Hexen things.
// Returns -1 for normal behavior, 0 to return false, and 1 to return true.
// I'm not sure I like it this way, but it will do for now.
virtual int SpecialMissileHit (AActor *victim);
// (virtual on the script side only)
int SpecialMissileHit (AActor *victim);
// Returns true if it's okay to switch target to "other" after being attacked by it.
virtual bool OkayToSwitchTarget (AActor *other);
bool OkayToSwitchTarget (AActor *other);
// Something just touched this actor.
virtual void Touch (AActor *toucher);
// Note: Although some of the inventory functions are virtual, this
// is not exposed to scripts, as the only class overriding them is
// APlayerPawn for some specific handling for players. None of this
// should ever be overridden by custom classes.
// Adds the item to this actor's inventory and sets its Owner.
virtual void AddInventory (AInventory *item);
// Give an item to the actor and pick it up.
// Returns true if the item pickup succeeded.
virtual bool GiveInventory (PClassInventory *type, int amount, bool givecheat = false);
bool GiveInventory (PClassInventory *type, int amount, bool givecheat = false);
// Removes the item from the inventory list.
virtual void RemoveInventory (AInventory *item);
@ -690,7 +702,7 @@ public:
virtual bool UseInventory (AInventory *item);
// Tosses an item out of the inventory.
virtual AInventory *DropInventory (AInventory *item);
AInventory *DropInventory (AInventory *item);
// Removes all items from the inventory.
void ClearInventory();
@ -732,7 +744,7 @@ public:
void ObtainInventory (AActor *other);
// Die. Now.
virtual bool Massacre ();
bool Massacre ();
// Transforms the actor into a finely-ground paste
virtual bool Grind(bool items);
@ -754,10 +766,10 @@ public:
DVector3 GetPortalTransition(double byoffset, sector_t **pSec = NULL);
// What species am I?
virtual FName GetSpecies();
FName GetSpecies();
// set translation
void SetTranslation(const char *trname);
void SetTranslation(FName trname);
double GetBobOffset(double ticfrac = 0) const
{
@ -957,7 +969,7 @@ public:
{
SetOrigin(Pos() + vel, true);
}
virtual void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(const DVector3 & npos, bool moving)
{
SetOrigin(npos.X, npos.Y, npos.Z, moving);
@ -969,7 +981,7 @@ public:
bool IsInsideVisibleAngles() const;
// Calculate amount of missile damage
virtual int GetMissileDamage(int mask, int add);
int GetMissileDamage(int mask, int add);
bool CanSeek(AActor *target) const;
@ -1367,7 +1379,7 @@ public:
Vel.Y = speed * Angles.Yaw.Sin();
}
void VelFromAngle(DAngle angle, double speed)
void VelFromAngle(double speed, DAngle angle)
{
Vel.X = speed * angle.Cos();
Vel.Y = speed * angle.Sin();
@ -1415,6 +1427,7 @@ public:
}
int ApplyDamageFactor(FName damagetype, int damage) const;
int GetModifiedDamage(FName damagetype, int damage, bool passive);
// begin of GZDoom specific additions
@ -1449,6 +1462,10 @@ public:
return base;
}
void Reinit()
{
base = nullptr;
}
private:
AActor *base;
int id;
@ -1532,6 +1549,7 @@ struct FTranslatedLineTarget
{
AActor *linetarget;
DAngle angleFromSource;
DAngle attackAngleFromSource;
bool unlinked; // found by a trace that went through an unlinked portal.
};

View file

@ -474,6 +474,11 @@ static AMColorset AMMod;
static AMColorset AMModOverlay;
void AM_ClearColorsets()
{
AMModOverlay.defined = false;
AMMod.defined = false;
}
//=============================================================================
//
//
@ -2964,8 +2969,8 @@ void AM_drawAuthorMarkers ()
// [RH] Draw any actors derived from AMapMarker on the automap.
// If args[0] is 0, then the actor's sprite is drawn at its own location.
// Otherwise, its sprite is drawn at the location of any actors whose TIDs match args[0].
TThinkerIterator<AMapMarker> it (STAT_MAPMARKER);
AMapMarker *mark;
TThinkerIterator<AActor> it ("MapMarker", STAT_MAPMARKER);
AActor *mark;
while ((mark = it.Next()) != NULL)
{

View file

@ -28,6 +28,7 @@ class FSerializer;
void AM_StaticInit();
void AM_ClearColorsets(); // reset data for a restart.
// Called by main loop.
bool AM_Responder (event_t* ev, bool last);

View file

@ -49,6 +49,10 @@ extern REGINFO ARegTail;
extern REGINFO CRegHead;
extern REGINFO CRegTail;
// List of class fields
extern REGINFO FRegHead;
extern REGINFO FRegTail;
// List of properties
extern REGINFO GRegHead;
extern REGINFO GRegTail;

View file

@ -15,14 +15,16 @@
#include "serializer.h"
#include "d_player.h"
IMPLEMENT_POINTY_CLASS(DBot)
DECLARE_POINTER(dest)
DECLARE_POINTER(prev)
DECLARE_POINTER(enemy)
DECLARE_POINTER(missile)
DECLARE_POINTER(mate)
DECLARE_POINTER(last_mate)
END_POINTERS
IMPLEMENT_CLASS(DBot, false, true)
IMPLEMENT_POINTERS_START(DBot)
IMPLEMENT_POINTER(dest)
IMPLEMENT_POINTER(prev)
IMPLEMENT_POINTER(enemy)
IMPLEMENT_POINTER(missile)
IMPLEMENT_POINTER(mate)
IMPLEMENT_POINTER(last_mate)
IMPLEMENT_POINTERS_END
DBot::DBot ()
: DThinker(STAT_BOT)

View file

@ -193,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd)
else
{
//*4 is for atmosphere, the chainsaws sounding and all..
no_fire = (Dist > MELEERANGE*4);
no_fire = (Dist > DEFMELEERANGE*4);
}
}
else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG)

View file

@ -21,6 +21,8 @@
#include "d_event.h"
#include "d_player.h"
#include "vectors.h"
#include "a_ammo.h"
#include "a_health.h"
static FRandom pr_botmove ("BotMove");

View file

@ -1,199 +0,0 @@
// This file is based on pragmas.h from Ken Silverman's original Build
// source code release. The functions in here are so simple and so
// basic that they can't be rewritten without being copycats of
// themselves. As such, they are uncopyrightable.
#if _MSC_VER
#pragma once
#endif
#if defined(__GNUC__) && !defined(__forceinline)
#define __forceinline __inline__ __attribute__((always_inline))
#endif
static __forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a*b)/c);
}
static __forceinline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a*b)>>c);
}
static __forceinline SDWORD MulScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 1); }
static __forceinline SDWORD MulScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 2); }
static __forceinline SDWORD MulScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 3); }
static __forceinline SDWORD MulScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 4); }
static __forceinline SDWORD MulScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 5); }
static __forceinline SDWORD MulScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 6); }
static __forceinline SDWORD MulScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 7); }
static __forceinline SDWORD MulScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 8); }
static __forceinline SDWORD MulScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 9); }
static __forceinline SDWORD MulScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 10); }
static __forceinline SDWORD MulScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 11); }
static __forceinline SDWORD MulScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 12); }
static __forceinline SDWORD MulScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 13); }
static __forceinline SDWORD MulScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 14); }
static __forceinline SDWORD MulScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 15); }
static __forceinline SDWORD MulScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 16); }
static __forceinline SDWORD MulScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 17); }
static __forceinline SDWORD MulScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 18); }
static __forceinline SDWORD MulScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 19); }
static __forceinline SDWORD MulScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 20); }
static __forceinline SDWORD MulScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 21); }
static __forceinline SDWORD MulScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 22); }
static __forceinline SDWORD MulScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 23); }
static __forceinline SDWORD MulScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 24); }
static __forceinline SDWORD MulScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 25); }
static __forceinline SDWORD MulScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 26); }
static __forceinline SDWORD MulScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 27); }
static __forceinline SDWORD MulScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 28); }
static __forceinline SDWORD MulScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 29); }
static __forceinline SDWORD MulScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 30); }
static __forceinline SDWORD MulScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 31); }
static __forceinline SDWORD MulScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 32); }
static __forceinline DWORD UMulScale16 (DWORD a, DWORD b) { return (DWORD)(((QWORD)a * b) >> 16); }
static __forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
{
return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> s);
}
static __forceinline SDWORD DMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 1); }
static __forceinline SDWORD DMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 2); }
static __forceinline SDWORD DMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 3); }
static __forceinline SDWORD DMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 4); }
static __forceinline SDWORD DMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 5); }
static __forceinline SDWORD DMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 6); }
static __forceinline SDWORD DMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 7); }
static __forceinline SDWORD DMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 8); }
static __forceinline SDWORD DMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 9); }
static __forceinline SDWORD DMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 10); }
static __forceinline SDWORD DMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 11); }
static __forceinline SDWORD DMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 12); }
static __forceinline SDWORD DMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 13); }
static __forceinline SDWORD DMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 14); }
static __forceinline SDWORD DMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 15); }
static __forceinline SDWORD DMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 16); }
static __forceinline SDWORD DMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 17); }
static __forceinline SDWORD DMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 18); }
static __forceinline SDWORD DMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 19); }
static __forceinline SDWORD DMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 20); }
static __forceinline SDWORD DMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 21); }
static __forceinline SDWORD DMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 22); }
static __forceinline SDWORD DMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 23); }
static __forceinline SDWORD DMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 24); }
static __forceinline SDWORD DMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 25); }
static __forceinline SDWORD DMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 26); }
static __forceinline SDWORD DMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 27); }
static __forceinline SDWORD DMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 28); }
static __forceinline SDWORD DMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 29); }
static __forceinline SDWORD DMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 30); }
static __forceinline SDWORD DMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 31); }
static __forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 32); }
static __forceinline SDWORD TMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 1); }
static __forceinline SDWORD TMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 2); }
static __forceinline SDWORD TMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 3); }
static __forceinline SDWORD TMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 4); }
static __forceinline SDWORD TMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 5); }
static __forceinline SDWORD TMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 6); }
static __forceinline SDWORD TMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 7); }
static __forceinline SDWORD TMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 8); }
static __forceinline SDWORD TMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 9); }
static __forceinline SDWORD TMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 10); }
static __forceinline SDWORD TMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 11); }
static __forceinline SDWORD TMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 12); }
static __forceinline SDWORD TMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 13); }
static __forceinline SDWORD TMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 14); }
static __forceinline SDWORD TMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 15); }
static __forceinline SDWORD TMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 16); }
static __forceinline SDWORD TMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 17); }
static __forceinline SDWORD TMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 18); }
static __forceinline SDWORD TMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 19); }
static __forceinline SDWORD TMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 20); }
static __forceinline SDWORD TMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 21); }
static __forceinline SDWORD TMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 22); }
static __forceinline SDWORD TMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 23); }
static __forceinline SDWORD TMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 24); }
static __forceinline SDWORD TMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 25); }
static __forceinline SDWORD TMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 26); }
static __forceinline SDWORD TMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 27); }
static __forceinline SDWORD TMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 28); }
static __forceinline SDWORD TMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 29); }
static __forceinline SDWORD TMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 30); }
static __forceinline SDWORD TMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 31); }
static __forceinline SDWORD TMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 32); }
static __forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
{
SQWORD x = ((SQWORD)a * b) >> c;
return x > 0x7FFFFFFFll ? 0x7FFFFFFF :
x < -0x80000000ll ? 0x80000000 :
(SDWORD)x;
}
static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a << c) / b);
}
static inline SDWORD DivScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 1) / b); }
static inline SDWORD DivScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 2) / b); }
static inline SDWORD DivScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 3) / b); }
static inline SDWORD DivScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 4) / b); }
static inline SDWORD DivScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 5) / b); }
static inline SDWORD DivScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 6) / b); }
static inline SDWORD DivScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 7) / b); }
static inline SDWORD DivScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 8) / b); }
static inline SDWORD DivScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 9) / b); }
static inline SDWORD DivScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 10) / b); }
static inline SDWORD DivScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 11) / b); }
static inline SDWORD DivScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 12) / b); }
static inline SDWORD DivScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 13) / b); }
static inline SDWORD DivScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 14) / b); }
static inline SDWORD DivScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 15) / b); }
static inline SDWORD DivScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 16) / b); }
static inline SDWORD DivScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 17) / b); }
static inline SDWORD DivScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 18) / b); }
static inline SDWORD DivScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 19) / b); }
static inline SDWORD DivScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 20) / b); }
static inline SDWORD DivScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 21) / b); }
static inline SDWORD DivScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 22) / b); }
static inline SDWORD DivScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 23) / b); }
static inline SDWORD DivScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 24) / b); }
static inline SDWORD DivScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 25) / b); }
static inline SDWORD DivScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 26) / b); }
static inline SDWORD DivScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 27) / b); }
static inline SDWORD DivScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 28) / b); }
static inline SDWORD DivScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 29) / b); }
static inline SDWORD DivScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 30) / b); }
static inline SDWORD DivScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 31) / b); }
static inline SDWORD DivScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 32) / b); }
static __forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
{
SDWORD *b2 = (SDWORD *)buff;
for (unsigned int i = 0; i != count; ++i)
{
b2[i] = clear;
}
}
static __forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
{
SWORD *b2 = (SWORD *)buff;
for (unsigned int i = 0; i != count; ++i)
{
b2[i] = clear;
}
}
static __forceinline SDWORD ksgn (SDWORD a)
{
if (a < 0) return -1;
else if (a > 0) return 1;
else return 0;
}

View file

@ -906,6 +906,16 @@ CCMD(info)
"the NOBLOCKMAP flag or have height/radius of 0.\n");
}
CCMD(myinfo)
{
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
players[consoleplayer].mo->GetClass()->TypeName.GetChars(),
players[consoleplayer].mo->health,
players[consoleplayer].mo->SpawnHealth());
PrintMiscActorInfo(players[consoleplayer].mo);
}
typedef bool (*ActorTypeChecker) (AActor *);
static bool IsActorAMonster(AActor *mo)
@ -1144,7 +1154,7 @@ CCMD(currentpos)
}
else
{
Printf("You are not in game!");
Printf("You are not in game!\n");
}
}

View file

@ -65,6 +65,7 @@
#include "g_level.h"
#include "d_event.h"
#include "d_player.h"
#include "gstrings.h"
#include "c_consolebuffer.h"
#include "gi.h"
@ -1522,8 +1523,6 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
buffer.Text.StripLeftRight();
Printf(127, TEXTCOLOR_WHITE "]%s\n", buffer.Text.GetChars());
AddCommandString(buffer.Text.LockBuffer());
buffer.Text.UnlockBuffer();
if (buffer.Text.Len() == 0)
{
@ -1567,7 +1566,21 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
}
}
HistPos = NULL;
buffer.SetString("");
{
// Work with a copy of command to avoid side effects caused by
// exception raised during execution, like with 'error' CCMD.
// It's problematic to maintain FString's lock symmetry.
static TArray<char> command;
const size_t length = buffer.Text.Len();
command.Resize(length + 1);
memcpy(&command[0], buffer.Text.GetChars(), length);
command[length] = '\0';
buffer.SetString("");
AddCommandString(&command[0]);
}
TabbedLast = false;
TabbedList = false;
break;
@ -1729,6 +1742,20 @@ void C_MidPrintBold (FFont *font, const char *msg)
}
}
DEFINE_ACTION_FUNCTION(DObject, C_MidPrint)
{
PARAM_PROLOGUE;
PARAM_STRING(font);
PARAM_STRING(text);
PARAM_BOOL_DEF(bold);
FFont *fnt = FFont::FindFont(font);
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
if (!bold) C_MidPrint(fnt, txt);
else C_MidPrintBold(fnt, txt);
return 0;
}
/****** Tab completion code ******/
struct TabData

View file

@ -1093,7 +1093,7 @@ BitVal (bitval)
ECVarType FFlagCVar::GetRealType () const
{
return CVAR_Dummy;
return CVAR_DummyBool;
}
UCVarValue FFlagCVar::GetGenericRep (ECVarType type) const
@ -1197,7 +1197,7 @@ BitVal (bitval)
ECVarType FMaskCVar::GetRealType () const
{
return CVAR_Dummy;
return CVAR_DummyInt;
}
UCVarValue FMaskCVar::GetGenericRep (ECVarType type) const

View file

@ -81,13 +81,17 @@ enum ECVarType
CVAR_Float,
CVAR_String,
CVAR_Color, // stored as CVAR_Int
CVAR_Dummy, // just redirects to another cvar
CVAR_DummyBool, // just redirects to another cvar
CVAR_DummyInt, // just redirects to another cvar
CVAR_Dummy, // Unknown
CVAR_GUID
};
class FConfigFile;
class AActor;
class FxCVar;
class FBaseCVar
{
public:
@ -211,6 +215,7 @@ void C_DeinitConsole();
class FBoolCVar : public FBaseCVar
{
friend class FxCVar;
public:
FBoolCVar (const char *name, bool def, uint32 flags, void (*callback)(FBoolCVar &)=NULL);
@ -236,6 +241,7 @@ protected:
class FIntCVar : public FBaseCVar
{
friend class FxCVar;
public:
FIntCVar (const char *name, int def, uint32 flags, void (*callback)(FIntCVar &)=NULL);
@ -263,6 +269,7 @@ protected:
class FFloatCVar : public FBaseCVar
{
friend class FxCVar;
public:
FFloatCVar (const char *name, float def, uint32 flags, void (*callback)(FFloatCVar &)=NULL);
@ -289,6 +296,7 @@ protected:
class FStringCVar : public FBaseCVar
{
friend class FxCVar;
public:
FStringCVar (const char *name, const char *def, uint32 flags, void (*callback)(FStringCVar &)=NULL);
~FStringCVar ();
@ -315,6 +323,7 @@ protected:
class FColorCVar : public FIntCVar
{
friend class FxCVar;
public:
FColorCVar (const char *name, int def, uint32 flags, void (*callback)(FColorCVar &)=NULL);
@ -339,6 +348,7 @@ protected:
class FFlagCVar : public FBaseCVar
{
friend class FxCVar;
public:
FFlagCVar (const char *name, FIntCVar &realvar, uint32 bitval);
@ -367,6 +377,7 @@ protected:
class FMaskCVar : public FBaseCVar
{
friend class FxCVar;
public:
FMaskCVar (const char *name, FIntCVar &realvar, uint32 bitval);

View file

@ -187,7 +187,7 @@ static const char *KeyConfCommands[] =
// CODE --------------------------------------------------------------------
IMPLEMENT_CLASS (DWaitingCommand)
IMPLEMENT_CLASS(DWaitingCommand, false, false)
void DWaitingCommand::Serialize(FSerializer &arc)
{
@ -225,7 +225,7 @@ void DWaitingCommand::Tick ()
}
}
IMPLEMENT_CLASS (DStoredCommand)
IMPLEMENT_CLASS(DStoredCommand, false, false)
DStoredCommand::DStoredCommand ()
{

View file

@ -15,6 +15,7 @@
#include "cmdlib.h"
#include "i_system.h"
#include "v_text.h"
#include "sc_man.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -324,7 +325,7 @@ FString ExtractFileBase (const char *path, bool include_extension)
//
//==========================================================================
int ParseHex (const char *hex)
int ParseHex (const char *hex, FScriptPosition *sc)
{
const char *str;
int num;
@ -342,7 +343,8 @@ int ParseHex (const char *hex)
else if (*str >= 'A' && *str <= 'F')
num += 10 + *str-'A';
else {
Printf ("Bad hex number: %s\n",hex);
if (!sc) Printf ("Bad hex number: %s\n",hex);
else sc->Message(MSG_WARNING, "Bad hex number: %s", hex);
return 0;
}
str++;
@ -351,21 +353,6 @@ int ParseHex (const char *hex)
return num;
}
//==========================================================================
//
// ParseNum
//
//==========================================================================
int ParseNum (const char *str)
{
if (str[0] == '$')
return ParseHex (str+1);
if (str[0] == '0' && str[1] == 'x')
return ParseHex (str+2);
return atol (str);
}
//==========================================================================
//
// IsNum
@ -632,7 +619,10 @@ int strbin (char *str)
if (*p >= '0' && *p <= '7')
c += *p-'0';
else
{
p--;
break;
}
p++;
}
*str++ = c;
@ -732,7 +722,10 @@ FString strbin1 (const char *start)
if (*p >= '0' && *p <= '7')
c += *p-'0';
else
{
p--;
break;
}
p++;
}
result << c;

View file

@ -33,8 +33,8 @@ void DefaultExtension (FString &path, const char *extension);
FString ExtractFilePath (const char *path);
FString ExtractFileBase (const char *path, bool keep_extension=false);
int ParseHex (const char *str);
int ParseNum (const char *str);
struct FScriptPosition;
int ParseHex(const char *str, FScriptPosition *sc = nullptr);
bool IsNum (const char *str); // [RH] added
char *copystring(const char *s);

View file

@ -80,6 +80,7 @@ enum
CP_CLEARSPECIAL,
CP_SETACTIVATION,
CP_SECTORFLOOROFFSET,
CP_SETSECTORSPECIAL,
CP_SETWALLYSCALE,
CP_SETTHINGZ,
CP_SETTAG,
@ -294,6 +295,15 @@ void ParseCompatibility()
sc.MustGetFloat();
CompatParams.Push(int(sc.Float*65536.));
}
else if (sc.Compare("setsectorspecial"))
{
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
CompatParams.Push(CP_SETSECTORSPECIAL);
sc.MustGetNumber();
CompatParams.Push(sc.Number);
sc.MustGetNumber();
CompatParams.Push(sc.Number);
}
else if (sc.Compare("setwallyscale"))
{
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
@ -529,6 +539,16 @@ void SetCompatibilityParams()
i += 3;
break;
}
case CP_SETSECTORSPECIAL:
{
const int index = CompatParams[i + 1];
if (index < numsectors)
{
sectors[index].special = CompatParams[i + 2];
}
i += 3;
break;
}
case CP_SETWALLYSCALE:
{
if (CompatParams[i+1] < numlines)

View file

@ -31,6 +31,7 @@
#include "templates.h"
#include "d_net.h"
#include "d_event.h"
#include "a_armor.h"
#define QUEUESIZE 128
#define MESSAGESIZE 128

View file

@ -70,7 +70,13 @@
#include "doomerrors.h"
#include "p_effect.h"
#include "serializer.h"
#include "thingdef.h"
#include "info.h"
#include "v_text.h"
#include "vmbuilder.h"
#include "a_armor.h"
#include "a_ammo.h"
#include "a_health.h"
// [SO] Just the way Randy said to do it :)
// [RH] Made this CVAR_SERVERINFO
@ -163,36 +169,25 @@ static TArray<CodePointerAlias> MBFCodePointers;
struct AmmoPerAttack
{
VMNativeFunction **func;
ENamedName func;
int ammocount;
VMFunction *ptr;
};
DECLARE_ACTION(A_Punch)
DECLARE_ACTION(A_FirePistol)
DECLARE_ACTION(A_FireShotgun)
DECLARE_ACTION(A_FireShotgun2)
DECLARE_ACTION(A_FireCGun)
DECLARE_ACTION(A_FireMissile)
DECLARE_ACTION(A_Saw)
DECLARE_ACTION(A_FirePlasma)
DECLARE_ACTION(A_FireBFG)
DECLARE_ACTION(A_FireOldBFG)
DECLARE_ACTION(A_FireRailgun)
// Default ammo use of the various weapon attacks
static AmmoPerAttack AmmoPerAttacks[] = {
{ &A_Punch_VMPtr, 0},
{ &A_FirePistol_VMPtr, 1},
{ &A_FireShotgun_VMPtr, 1},
{ &A_FireShotgun2_VMPtr, 2},
{ &A_FireCGun_VMPtr, 1},
{ &A_FireMissile_VMPtr, 1},
{ &A_Saw_VMPtr, 0},
{ &A_FirePlasma_VMPtr, 1},
{ &A_FireBFG_VMPtr, -1}, // uses deh.BFGCells
{ &A_FireOldBFG_VMPtr, 1},
{ &A_FireRailgun_VMPtr, 1},
{ NULL, 0}
{ NAME_A_Punch, 0},
{ NAME_A_FirePistol, 1},
{ NAME_A_FireShotgun, 1},
{ NAME_A_FireShotgun2, 2},
{ NAME_A_FireCGun, 1},
{ NAME_A_FireMissile, 1},
{ NAME_A_Saw, 0},
{ NAME_A_FirePlasma, 1},
{ NAME_A_FireBFG, -1}, // uses deh.BFGCells
{ NAME_A_FireOldBFG, 1},
{ NAME_A_FireRailgun, 1},
{ NAME_None, 0}
};
@ -220,6 +215,12 @@ DehInfo deh =
40, // BFG cells per shot
};
DEFINE_FIELD_X(DehInfo, DehInfo, MaxSoulsphere)
DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionStyle)
DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionAlpha)
DEFINE_FIELD_X(DehInfo, DehInfo, NoAutofreeze)
DEFINE_FIELD_X(DehInfo, DehInfo, BFGCells)
// Doom identified pickup items by their sprites. ZDoom prefers to use their
// class type to identify them instead. To support the traditional Doom
// behavior, for every thing touched by dehacked that has the MF_PICKUP flag,
@ -227,9 +228,11 @@ DehInfo deh =
// from the original actor's defaults. The original actor is then changed to
// spawn the new class.
IMPLEMENT_POINTY_CLASS (ADehackedPickup)
DECLARE_POINTER (RealPickup)
END_POINTERS
IMPLEMENT_CLASS(ADehackedPickup, false, true)
IMPLEMENT_POINTERS_START(ADehackedPickup)
IMPLEMENT_POINTER(RealPickup)
IMPLEMENT_POINTERS_END
TArray<PClassActor *> TouchedActors;
@ -794,7 +797,7 @@ void SetDehParams(FState *state, int codepointer)
// Let's identify the codepointer we're dealing with.
PFunction *sym;
sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
sym = dyn_cast<PFunction>(RUNTIME_CLASS(AStateProvider)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
if (sym == NULL) return;
if (codepointer < 0 || (unsigned)codepointer >= countof(MBFCodePointerFactories))
@ -804,22 +807,26 @@ void SetDehParams(FState *state, int codepointer)
}
else
{
VMFunctionBuilder buildit;
int numargs = sym->GetImplicitArgs();
VMFunctionBuilder buildit(numargs);
// Allocate registers used to pass parameters in.
// self, stateowner, state (all are pointers)
buildit.Registers[REGT_POINTER].Get(NAP);
buildit.Registers[REGT_POINTER].Get(numargs);
// Emit code to pass the standard action function parameters.
for (int i = 0; i < NAP; i++)
for (int i = 0; i < numargs; i++)
{
buildit.Emit(OP_PARAM, 0, REGT_POINTER, i);
}
// Emit code for action parameters.
int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2);
buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), NAP + argcount, 0);
buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), numargs + argcount, 0);
// Attach it to the state.
VMScriptFunction *sfunc = buildit.MakeFunction();
sfunc->NumArgs = NAP;
VMScriptFunction *sfunc = new VMScriptFunction;
buildit.MakeFunction(sfunc);
sfunc->NumArgs = numargs;
sfunc->ImplicitArgs = numargs;
state->SetAction(sfunc);
sfunc->PrintableName.Format("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2);
}
}
@ -1466,15 +1473,16 @@ static int PatchFrame (int frameNum)
if (info != &dummy)
{
info->DefineFlags |= SDF_DEHACKED; // Signals the state has been modified by dehacked
info->StateFlags |= STF_DEHACKED; // Signals the state has been modified by dehacked
if ((unsigned)(frame & 0x7fff) > 63)
{
Printf ("Frame %d: Subnumber must be in range [0,63]\n", frameNum);
Printf("Frame %d: Subnumber must be in range [0,63]\n", frameNum);
}
info->Tics = tics;
info->Misc1 = misc1;
info->Frame = frame & 0x3f;
info->Fullbright = frame & 0x8000 ? true : false;
if (frame & 0x8000) info->StateFlags |= STF_FULLBRIGHT;
else info->StateFlags &= ~STF_FULLBRIGHT;
}
return result;
@ -2101,23 +2109,24 @@ static int PatchCodePtrs (int dummy)
if (!symname.CompareNoCase(MBFCodePointers[i].alias))
{
symname = MBFCodePointers[i].name;
Printf("%s --> %s\n", MBFCodePointers[i].alias, MBFCodePointers[i].name.GetChars());
DPrintf(DMSG_SPAMMY, "%s --> %s\n", MBFCodePointers[i].alias, MBFCodePointers[i].name.GetChars());
}
}
// This skips the action table and goes directly to the internal symbol table
// DEH compatible functions are easy to recognize.
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true));
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AStateProvider)->Symbols.FindSymbol(symname, true));
if (sym == NULL)
{
Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2);
Printf(TEXTCOLOR_RED "Frame %d: Unknown code pointer '%s'\n", frame, Line2);
}
else
{
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
if ((sym->Flags & (VARF_Method | VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional)))
unsigned numargs = sym->GetImplicitArgs();
if ((sym->Variants[0].Flags & VARF_Virtual || (args.Size() > numargs && !(args[numargs] & VARF_Optional))))
{
Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
Printf(TEXTCOLOR_RED "Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
sym = NULL;
}
}
@ -2715,11 +2724,11 @@ static bool LoadDehSupp ()
}
else
{
// all relevant code pointers are either defined in AInventory
// all relevant code pointers are either defined in AStateProvider
// or AActor so this will find all of them.
FString name = "A_";
name << sc.String;
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true));
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AStateProvider)->Symbols.FindSymbol(name, true));
if (sym == NULL)
{
sc.ScriptError("Unknown code pointer '%s'", sc.String);
@ -2727,7 +2736,8 @@ static bool LoadDehSupp ()
else
{
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
if ((sym->Flags & (VARF_Method|VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional)))
unsigned numargs = sym->GetImplicitArgs();
if ((sym->Variants[0].Flags & VARF_Virtual || (args.Size() > numargs && !(args[numargs] & VARF_Optional))))
{
sc.ScriptMessage("Incompatible code pointer '%s'", sc.String);
}
@ -3075,9 +3085,14 @@ void FinishDehPatch ()
break; // State has already been checked so we reached a loop
}
StateVisited[state] = true;
for(unsigned j = 0; AmmoPerAttacks[j].func != NULL; j++)
for(unsigned j = 0; AmmoPerAttacks[j].func != NAME_None; j++)
{
if (state->ActionFunc == *AmmoPerAttacks[j].func)
if (AmmoPerAttacks[j].ptr == nullptr)
{
auto p = dyn_cast<PFunction>(RUNTIME_CLASS(AStateProvider)->Symbols.FindSymbol(AmmoPerAttacks[j].func, true));
if (p != nullptr) AmmoPerAttacks[j].ptr = p->Variants[0].Implementation;
}
if (state->ActionFunc == AmmoPerAttacks[j].ptr)
{
found = true;
int use = AmmoPerAttacks[j].ammocount;
@ -3131,7 +3146,7 @@ bool ADehackedPickup::TryPickup (AActor *&toucher)
return false;
}
const char *ADehackedPickup::PickupMessage ()
FString ADehackedPickup::PickupMessage ()
{
if (RealPickup != nullptr)
return RealPickup->PickupMessage ();
@ -3141,7 +3156,7 @@ const char *ADehackedPickup::PickupMessage ()
bool ADehackedPickup::ShouldStay ()
{
if (RealPickup != nullptr)
return RealPickup->ShouldStay ();
return RealPickup->CallShouldStay ();
else return true;
}

View file

@ -41,8 +41,8 @@ class ADehackedPickup : public AInventory
DECLARE_CLASS (ADehackedPickup, AInventory)
HAS_OBJECT_POINTERS
public:
void Destroy ();
const char *PickupMessage ();
void Destroy() override;
FString PickupMessage ();
bool ShouldRespawn ();
bool ShouldStay ();
bool TryPickup (AActor *&toucher);

View file

@ -193,10 +193,10 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize)
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->FgColor = V_GetColor(NULL, sc.String);
iwad->FgColor = V_GetColor(NULL, sc);
sc.MustGetStringName(",");
sc.MustGetString();
iwad->BkColor = V_GetColor(NULL, sc.String);
iwad->BkColor = V_GetColor(NULL, sc);
}
else if (sc.Compare("Load"))
{

View file

@ -206,6 +206,11 @@ CUSTOM_CVAR (String, vid_cursor, "None", CVAR_ARCHIVE | CVAR_NOINITCALL)
}
}
// Controlled by startup dialog
CVAR (Bool, disableautoload, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
CVAR (Bool, autoloadbrightmaps, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
CVAR (Bool, autoloadlights, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
bool wantToRestart;
bool DrawFSHUD; // [RH] Draw fullscreen HUD?
TArray<FString> allwads;
@ -1028,6 +1033,12 @@ void D_DoomLoop ()
}
D_ErrorCleanup ();
}
catch (CVMAbortException &error)
{
error.MaybePrintMessage();
Printf("%s", error.stacktrace.GetChars());
D_ErrorCleanup();
}
}
}
@ -1839,10 +1850,10 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
else if (!nextKey.CompareNoCase("STARTUPCOLORS"))
{
sc.MustGetString();
DoomStartupInfo.FgColor = V_GetColor(NULL, sc.String);
DoomStartupInfo.FgColor = V_GetColor(NULL, sc);
sc.MustGetStringName(",");
sc.MustGetString();
DoomStartupInfo.BkColor = V_GetColor(NULL, sc.String);
DoomStartupInfo.BkColor = V_GetColor(NULL, sc);
}
else if (!nextKey.CompareNoCase("STARTUPTYPE"))
{
@ -2033,7 +2044,24 @@ static void AddAutoloadFiles(const char *autoname)
{
LumpFilterIWAD.Format("%s.", autoname); // The '.' is appened to simplify parsing the string
if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload"))
// [SP] Dialog reaction - load lights.pk3 and brightmaps.pk3 based on user choices
if (!(gameinfo.flags & GI_SHAREWARE))
{
if (autoloadlights)
{
const char *lightswad = BaseFileSearch ("lights.pk3", NULL);
if (lightswad)
D_AddFile (allwads, lightswad);
}
if (autoloadbrightmaps)
{
const char *bmwad = BaseFileSearch ("brightmaps.pk3", NULL);
if (bmwad)
D_AddFile (allwads, bmwad);
}
}
if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload") && !disableautoload)
{
FString file;
@ -2593,44 +2621,48 @@ void D_DoomMain (void)
G_DeferedPlayDemo (v);
D_DoomLoop (); // never returns
}
v = Args->CheckValue ("-timedemo");
if (v)
else
{
G_TimeDemo (v);
D_DoomLoop (); // never returns
}
if (gameaction != ga_loadgame && gameaction != ga_loadgamehidecon)
{
if (autostart || netgame)
v = Args->CheckValue("-timedemo");
if (v)
{
// Do not do any screenwipes when autostarting a game.
if (!Args->CheckParm("-warpwipe"))
{
NoWipe = TICRATE;
}
CheckWarpTransMap (startmap, true);
if (demorecording)
G_BeginRecording (startmap);
G_InitNew (startmap, false);
if (StoredWarp.IsNotEmpty())
{
AddCommandString(StoredWarp.LockBuffer());
StoredWarp = NULL;
}
G_TimeDemo(v);
D_DoomLoop(); // never returns
}
else
{
D_StartTitle (); // start up intro loop
if (gameaction != ga_loadgame && gameaction != ga_loadgamehidecon)
{
if (autostart || netgame)
{
// Do not do any screenwipes when autostarting a game.
if (!Args->CheckParm("-warpwipe"))
{
NoWipe = TICRATE;
}
CheckWarpTransMap(startmap, true);
if (demorecording)
G_BeginRecording(startmap);
G_InitNew(startmap, false);
if (StoredWarp.IsNotEmpty())
{
AddCommandString(StoredWarp.LockBuffer());
StoredWarp = NULL;
}
}
else
{
D_StartTitle(); // start up intro loop
}
}
else if (demorecording)
{
G_BeginRecording(NULL);
}
atterm(D_QuitNetGame); // killough
}
}
else if (demorecording)
{
G_BeginRecording (NULL);
}
atterm (D_QuitNetGame); // killough
}
else
{
@ -2644,7 +2676,6 @@ void D_DoomMain (void)
}
D_DoomLoop (); // this only returns if a 'restart' CCMD is given.
//
// Clean up after a restart
//
@ -2655,6 +2686,7 @@ void D_DoomMain (void)
M_ClearMenus(); // close menu if open
F_EndFinale(); // If an intermission is active, end it now
AM_ClearColorsets();
// clean up game state
ST_Clear();

View file

@ -62,6 +62,7 @@
#include "p_spec.h"
#include "hardware.h"
#include "r_utility.h"
#include "a_keys.h"
#include "intermission/intermission.h"
EXTERN_CVAR (Int, disableautosave)

View file

@ -31,6 +31,7 @@
#include "doomstat.h"
#include "a_artifacts.h"
#include "a_weapons.h"
// The player data structure depends on a number
// of other structs: items (internal inventory),
@ -81,7 +82,6 @@ public:
FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
void SetPainFlash(FName type, PalEntry color);
bool GetPainFlash(FName type, PalEntry *color) const;
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
FString DisplayName; // Display name (used in menus, etc.)
FString SoundClass; // Sound class
@ -106,29 +106,36 @@ public:
virtual void Serialize(FSerializer &arc);
virtual void PostBeginPlay();
virtual void Tick();
virtual void AddInventory (AInventory *item);
virtual void RemoveInventory (AInventory *item);
virtual bool UseInventory (AInventory *item);
virtual void MarkPrecacheSounds () const;
virtual void PostBeginPlay() override;
virtual void Tick() override;
virtual void AddInventory (AInventory *item) override;
virtual void RemoveInventory (AInventory *item) override;
virtual bool UseInventory (AInventory *item) override;
virtual void MarkPrecacheSounds () const override;
virtual void BeginPlay () override;
virtual void Die (AActor *source, AActor *inflictor, int dmgflags) override;
virtual bool UpdateWaterLevel (bool splash) override;
virtual void PlayIdle ();
virtual void PlayRunning ();
virtual void ThrowPoisonBag ();
virtual void TweakSpeeds (double &forwardmove, double &sidemove);
virtual void MorphPlayerThink ();
virtual void ActivateMorphWeapon ();
bool ResetAirSupply (bool playgasp = true);
int GetMaxHealth() const;
void TweakSpeeds (double &forwardmove, double &sidemove);
void MorphPlayerThink ();
void ActivateMorphWeapon ();
AWeapon *PickNewWeapon (PClassAmmo *ammotype);
AWeapon *BestWeapon (PClassAmmo *ammotype);
void CheckWeaponSwitch(PClassAmmo *ammotype);
virtual void GiveDeathmatchInventory ();
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
void GiveDeathmatchInventory ();
void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
void SetupWeaponSlots ();
void GiveDefaultInventory ();
// These are virtual on the script side only.
void PlayIdle();
void PlayRunning();
void PlayAttacking ();
void PlayAttacking2 ();
const char *GetSoundClass () const;
enum EInvulState
@ -139,8 +146,6 @@ public:
INVUL_GetAlpha
};
void BeginPlay ();
void Die (AActor *source, AActor *inflictor, int dmgflags);
int crouchsprite;
int MaxHealth;
@ -172,10 +177,6 @@ public:
// [SP] ViewBob Multiplier
double ViewBob;
bool UpdateWaterLevel (bool splash);
bool ResetAirSupply (bool playgasp = true);
int GetMaxHealth() const;
};
class APlayerChunk : public APlayerPawn
@ -254,11 +255,10 @@ enum
WF_USER4OK = 1 << 11,
};
#define WPIECE1 1
#define WPIECE2 2
#define WPIECE3 4
#define WP_NOCHANGE ((AWeapon*)~0)
// The VM cannot deal with this as an invalid pointer because it performs a read barrier on every object pointer read.
// This doesn't have to point to a valid weapon, though, because WP_NOCHANGE is never dereferenced, but it must point to a valid object
// and the class descriptor just works fine for that.
#define WP_NOCHANGE ((AWeapon*)RUNTIME_CLASS_CASTLESS(AWeapon))
#define MAXPLAYERNAME 15

View file

@ -119,9 +119,11 @@ protected:
DDecalThinker () : DThinker (STAT_DECALTHINKER) {}
};
IMPLEMENT_POINTY_CLASS (DDecalThinker)
DECLARE_POINTER (TheDecal)
END_POINTERS
IMPLEMENT_CLASS(DDecalThinker, false, true)
IMPLEMENT_POINTERS_START(DDecalThinker)
IMPLEMENT_POINTER(TheDecal)
IMPLEMENT_POINTERS_END
void DDecalThinker::Serialize(FSerializer &arc)
{
@ -530,7 +532,7 @@ void FDecalLib::ParseDecal (FScanner &sc)
sc.MustGetString ();
if (!sc.Compare("BloodDefault"))
{
newdecal.ShadeColor = V_GetColor (NULL, sc.String);
newdecal.ShadeColor = V_GetColor (NULL, sc);
}
else
{
@ -545,8 +547,8 @@ void FDecalLib::ParseDecal (FScanner &sc)
case DECAL_COLORS:
DWORD startcolor, endcolor;
sc.MustGetString (); startcolor = V_GetColor (NULL, sc.String);
sc.MustGetString (); endcolor = V_GetColor (NULL, sc.String);
sc.MustGetString (); startcolor = V_GetColor (NULL, sc);
sc.MustGetString (); endcolor = V_GetColor (NULL, sc);
newdecal.Translation = GenerateTranslation (startcolor, endcolor)->Index;
break;
@ -817,7 +819,7 @@ void FDecalLib::ParseColorchanger (FScanner &sc)
else if (sc.Compare ("Color"))
{
sc.MustGetString ();
goal = V_GetColor (NULL, sc.String);
goal = V_GetColor (NULL, sc);
}
else
{
@ -1151,7 +1153,7 @@ FDecalAnimator::~FDecalAnimator ()
{
}
IMPLEMENT_CLASS (DDecalFader)
IMPLEMENT_CLASS(DDecalFader, false, false)
void DDecalFader::Serialize(FSerializer &arc)
{
@ -1200,7 +1202,7 @@ DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
return fader;
}
IMPLEMENT_CLASS (DDecalStretcher)
IMPLEMENT_CLASS(DDecalStretcher, false, false)
void DDecalStretcher::Serialize(FSerializer &arc)
{
@ -1230,6 +1232,7 @@ DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) c
}
else
{
thinker->GoalX = 0;
thinker->bStretchX = false;
}
if (GoalY >= 0)
@ -1239,6 +1242,7 @@ DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) c
}
else
{
thinker->GoalY = 0;
thinker->bStretchY = false;
}
thinker->bStarted = false;
@ -1288,7 +1292,7 @@ void DDecalStretcher::Tick ()
}
}
IMPLEMENT_CLASS (DDecalSlider)
IMPLEMENT_CLASS(DDecalSlider, false, false)
void DDecalSlider::Serialize(FSerializer &arc)
{
@ -1368,8 +1372,7 @@ FDecalAnimator *FDecalLib::FindAnimator (const char *name)
return NULL;
}
IMPLEMENT_CLASS (DDecalColorer)
IMPLEMENT_CLASS(DDecalColorer, false, false)
void DDecalColorer::Serialize(FSerializer &arc)
{

View file

@ -48,6 +48,7 @@
#include "a_sharedglobal.h"
#include "dsectoreffect.h"
#include "serializer.h"
#include "virtual.h"
//==========================================================================
//
@ -57,16 +58,21 @@
ClassReg DObject::RegistrationInfo =
{
NULL, // MyClass
"DObject", // Name
NULL, // ParentType
NULL, // Pointers
&DObject::InPlaceConstructor, // ConstructNative
sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum
nullptr, // MyClass
"DObject", // Name
nullptr, // ParentType
nullptr,
nullptr, // Pointers
&DObject::InPlaceConstructor, // ConstructNative
nullptr,
sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum
};
_DECLARE_TI(DObject)
// This bit is needed in the playsim - but give it a less crappy name.
DEFINE_FIELD_BIT(DObject,ObjectFlags, bDestroyed, OF_EuthanizeMe)
//==========================================================================
//
//
@ -349,6 +355,13 @@ void DObject::Destroy ()
ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;
}
DEFINE_ACTION_FUNCTION(DObject, Destroy)
{
PARAM_SELF_PROLOGUE(DObject);
self->Destroy();
return 0;
}
//==========================================================================
//
//
@ -410,7 +423,7 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
//
//==========================================================================
size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld, bool scandefaults)
{
DObject *probe;
size_t changed = 0;
@ -425,6 +438,20 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
last = probe;
}
if (scandefaults)
{
for (auto p : PClassActor::AllActorClasses)
{
auto def = GetDefaultByType(p);
if (def != nullptr)
{
def->Class = p;
def->DObject::PointerSubstitution(old, notOld);
def->Class = nullptr; // reset pointer. Defaults should not have a valid class pointer.
}
}
}
// Go through the bodyque.
for (i = 0; i < BODYQUESIZE; ++i)
{

View file

@ -36,6 +36,7 @@
#include <stdlib.h>
#include "doomtype.h"
#include "i_system.h"
class PClass;
@ -109,8 +110,10 @@ struct ClassReg
PClass *MyClass;
const char *Name;
ClassReg *ParentType;
ClassReg *_VMExport;
const size_t *Pointers;
void (*ConstructNative)(void *);
void(*InitNatives)();
unsigned int SizeOf:28;
unsigned int MetaClassNum:4;
@ -124,8 +127,8 @@ enum EInPlace { EC_InPlace };
public: \
virtual PClass *StaticType() const; \
static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \
private: \
typedef parent Super; \
private: \
typedef cls ThisClass;
#define DECLARE_ABSTRACT_CLASS_WITH_META(cls,parent,meta) \
@ -147,11 +150,6 @@ protected: \
#define HAS_OBJECT_POINTERS \
static const size_t PointerOffsets[];
// Taking the address of a field in an object at address 1 instead of
// address 0 keeps GCC from complaining about possible misuse of offsetof.
#define DECLARE_POINTER(field) (size_t)&((ThisClass*)1)->field - 1,
#define END_POINTERS ~(size_t)0 };
#if defined(_MSC_VER)
# pragma section(".creg$u",read)
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg * const cls::RegistrationInfoPtr = &cls::RegistrationInfo;
@ -159,36 +157,41 @@ protected: \
# define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
#endif
#define _IMP_PCLASS(cls,ptrs,create) \
#define _IMP_PCLASS(cls, ptrs, create) \
ClassReg cls::RegistrationInfo = {\
NULL, \
nullptr, \
#cls, \
&cls::Super::RegistrationInfo, \
nullptr, \
ptrs, \
create, \
nullptr, \
sizeof(cls), \
cls::MetaClassNum }; \
_DECLARE_TI(cls) \
PClass *cls::StaticType() const { return RegistrationInfo.MyClass; }
#define _IMP_CREATE_OBJ(cls) \
void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; }
#define IMPLEMENT_CLASS(cls, isabstract, ptrs) \
_X_CONSTRUCTOR_##isabstract(cls) \
_IMP_PCLASS(cls, _X_POINTERS_##ptrs(cls), _X_ABSTRACT_##isabstract(cls))
#define IMPLEMENT_POINTY_CLASS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor) \
const size_t cls::PointerOffsets[] = {
// Taking the address of a field in an object at address 1 instead of
// address 0 keeps GCC from complaining about possible misuse of offsetof.
#define IMPLEMENT_POINTERS_START(cls) const size_t cls::PointerOffsets[] = {
#define IMPLEMENT_POINTER(field) (size_t)&((ThisClass*)1)->field - 1,
#define IMPLEMENT_POINTERS_END ~(size_t)0 };
#define IMPLEMENT_CLASS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,NULL,cls::InPlaceConstructor)
#define IMPLEMENT_ABSTRACT_CLASS(cls) \
_IMP_PCLASS(cls,NULL,NULL)
#define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
const size_t cls::PointerOffsets[] = {
// Possible arguments for the IMPLEMENT_CLASS macro
#define _X_POINTERS_true(cls) cls::PointerOffsets
#define _X_POINTERS_false(cls) nullptr
#define _X_FIELDS_true(cls) nullptr
#define _X_FIELDS_false(cls) nullptr
#define _X_CONSTRUCTOR_true(cls)
#define _X_CONSTRUCTOR_false(cls) void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; }
#define _X_ABSTRACT_true(cls) nullptr
#define _X_ABSTRACT_false(cls) cls::InPlaceConstructor
#define _X_VMEXPORT_true(cls) nullptr
#define _X_VMEXPORT_false(cls) nullptr
enum EObjectFlags
{
@ -201,7 +204,6 @@ enum EObjectFlags
OF_EuthanizeMe = 1 << 5, // Object wants to die
OF_Cleanup = 1 << 6, // Object is now being deleted by the collector
OF_YesReallyDelete = 1 << 7, // Object is being deleted outside the collector, and this is okay, so don't print a warning
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
OF_WhiteBits = OF_White0 | OF_White1,
OF_MarkBits = OF_WhiteBits | OF_Black,
@ -210,6 +212,8 @@ enum EObjectFlags
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
OF_SuperCall = 1 << 12, // A super call from the VM is about to be performed
};
template<class T> class TObjPtr;
@ -472,13 +476,13 @@ public:
// that don't call their base class.
void CheckIfSerialized () const;
virtual void Destroy ();
virtual void Destroy();
// If you need to replace one object with another and want to
// change any pointers from the old object to the new object,
// use this method.
virtual size_t PointerSubstitution (DObject *old, DObject *notOld);
static size_t StaticPointerSubstitution (DObject *old, DObject *notOld);
static size_t StaticPointerSubstitution (DObject *old, DObject *notOld, bool scandefaults = false);
PClass *GetClass() const
{
@ -574,6 +578,8 @@ protected:
}
};
class AInventory;//
// When you write to a pointer to an Object, you must call this for
// proper bookkeeping in case the Object holding this pointer has
// already been processed by the GC.

View file

@ -124,7 +124,8 @@ public:
int PolyNum;
int SideNum;
};
IMPLEMENT_CLASS(DSectorMarker)
IMPLEMENT_CLASS(DSectorMarker, false, false)
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -5,20 +5,36 @@
#error You must #include "dobject.h" to get dobjtype.h
#endif
#include "vm.h"
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
#include "vm.h"
// Variable/parameter/field flags -------------------------------------------
// Making all these different storage types use a common set of flags seems
// like the simplest thing to do.
#define VARF_Optional (1<<0) // func param is optional
#define VARF_Method (1<<1) // func has an implied self parameter
#define VARF_Action (1<<2) // func has implied owner and state parameters
#define VARF_Native (1<<3) // func is native code/don't auto serialize field
#define VARF_ReadOnly (1<<4) // field is read only, do not write to it
enum
{
VARF_Optional = (1<<0), // func param is optional
VARF_Method = (1<<1), // func has an implied self parameter
VARF_Action = (1<<2), // func has implied owner and state parameters
VARF_Native = (1<<3), // func is native code, field is natively defined
VARF_ReadOnly = (1<<4), // field is read only, do not write to it
VARF_Private = (1<<5), // field is private to containing class
VARF_Protected = (1<<6), // field is only accessible by containing class and children.
VARF_Deprecated = (1<<7), // Deprecated fields should output warnings when used.
VARF_Virtual = (1<<8), // function is virtual
VARF_Final = (1<<9), // Function may not be overridden in subclasses
VARF_In = (1<<10),
VARF_Out = (1<<11),
VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures)
VARF_Static = (1<<13), // static class data (by necessity read only.)
VARF_InternalAccess = (1<<14), // overrides VARF_ReadOnly for internal script code.
VARF_Override = (1<<15), // overrides a virtual function from the parent class.
VARF_Ref = (1<<16), // argument is passed by reference.
VARF_Transient = (1<<17) // don't auto serialize field.
};
// Symbol information -------------------------------------------------------
@ -57,7 +73,6 @@ struct StateCallData;
class VMFrameStack;
struct VMValue;
struct VMReturn;
typedef int (*actionf_p)(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/
class VMFunction;
// A VM function ------------------------------------------------------------
@ -86,18 +101,6 @@ public:
PSymbolType() : PSymbol(NAME_None) {}
};
// A symbol for a compiler tree node ----------------------------------------
class PSymbolTreeNode : public PSymbol
{
DECLARE_CLASS(PSymbolTreeNode, PSymbol);
public:
struct ZCC_NamedNode *Node;
PSymbolTreeNode(FName name, struct ZCC_NamedNode *node) : PSymbol(name), Node(node) {}
PSymbolTreeNode() : PSymbol(NAME_None) {}
};
// A symbol table -----------------------------------------------------------
struct PSymbolTable
@ -111,6 +114,10 @@ struct PSymbolTable
// Sets the table to use for searches if this one doesn't contain the
// requested symbol.
void SetParentTable (PSymbolTable *parent);
PSymbolTable *GetParentTable() const
{
return ParentSymbolTable;
}
// Finds a symbol in the table, optionally searching parent tables
// as well.
@ -120,6 +127,7 @@ struct PSymbolTable
// specific symbol table the symbol was found in.
PSymbol *FindSymbolInTable(FName symname, PSymbolTable *&symtable);
// Places the symbol in the table and returns a pointer to it or NULL if
// a symbol with the same name is already in the table. This symbol is
// not copied and will be freed when the symbol table is destroyed.
@ -132,15 +140,33 @@ struct PSymbolTable
// Frees all symbols from this table.
void ReleaseSymbols();
private:
typedef TMap<FName, PSymbol *> MapType;
MapType::Iterator GetIterator()
{
return MapType::Iterator(Symbols);
}
private:
PSymbolTable *ParentSymbolTable;
MapType Symbols;
friend class DObject;
};
// A symbol for a compiler tree node ----------------------------------------
class PSymbolTreeNode : public PSymbol
{
DECLARE_CLASS(PSymbolTreeNode, PSymbol);
public:
struct ZCC_TreeNode *Node;
PSymbolTreeNode(FName name, struct ZCC_TreeNode *node) : PSymbol(name), Node(node) {}
PSymbolTreeNode() : PSymbol(NAME_None) {}
};
extern PSymbolTable GlobalSymbols;
// Basic information shared by all types ------------------------------------
@ -179,6 +205,7 @@ class PType : public PTypeBase
HAS_OBJECT_POINTERS;
protected:
enum { MetaClassNum = CLASSREG_PClassType };
public:
typedef PClassType MetaClass;
MetaClass *GetClass() const;
@ -196,10 +223,13 @@ public:
unsigned int Align; // this type's preferred alignment
PType *HashNext; // next type in this type table
PSymbolTable Symbols;
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
FString mDescriptiveName;
BYTE loadOp, storeOp, moveOp, RegType, RegCount;
PType();
PType(unsigned int size, unsigned int align);
PType(unsigned int size = 1, unsigned int align = 1);
virtual ~PType();
virtual bool isNumeric() { return false; }
bool AddConversion(PType *target, void (*convertconst)(ZCC_ExprConstant *, class FSharedStringArena &));
@ -224,6 +254,7 @@ public:
// initialization when the object is created and destruction when the
// object is destroyed.
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const;
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
@ -240,14 +271,33 @@ public:
virtual double GetValueFloat(void *addr) const;
// Gets the opcode to store from a register to memory
virtual int GetStoreOp() const;
int GetStoreOp() const
{
return storeOp;
}
// Gets the opcode to load from memory to a register
virtual int GetLoadOp() const;
int GetLoadOp() const
{
return loadOp;
}
// Gets the opcode to move from register to another register
int GetMoveOp() const
{
return moveOp;
}
// Gets the register type for this type
virtual int GetRegType() const;
int GetRegType() const
{
return RegType;
}
int GetRegCount() const
{
return RegCount;
}
// Returns true if this type matches the two identifiers. Referring to the
// above table, any type is identified by at most two characteristics. Each
// type that implements this function will cast these to the appropriate type.
@ -259,6 +309,8 @@ public:
// Get the type IDs used by IsMatch
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
const char *DescriptiveName() const;
size_t PropagateMark();
static void StaticInit();
@ -318,7 +370,7 @@ class PErrorType : public PType
{
DECLARE_CLASS(PErrorType, PType);
public:
PErrorType() : PType(0, 1) {}
PErrorType(int which = 1) : PType(0, which) {}
};
class PVoidType : public PType
@ -351,8 +403,12 @@ public:
PTypeBase *Outer; // object this type is contained within
FName TypeName; // this type's name
PNamedType() : Outer(NULL) {}
PNamedType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {}
PNamedType() : Outer(NULL) {
mDescriptiveName = "NamedType";
}
PNamedType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
mDescriptiveName = name.GetChars();
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
@ -365,7 +421,7 @@ class PInt : public PBasicType
{
DECLARE_CLASS(PInt, PBasicType);
public:
PInt(unsigned int size, bool unsign);
PInt(unsigned int size, bool unsign, bool compatible = true);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
@ -374,13 +430,13 @@ public:
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetRegType() const;
virtual bool isNumeric() override { return IntCompatible; }
bool Unsigned;
bool IntCompatible;
protected:
PInt();
void SetOps();
};
class PBool : public PInt
@ -403,11 +459,10 @@ public:
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetRegType() const;
virtual bool isNumeric() override { return true; }
protected:
PFloat();
void SetOps();
private:
struct SymbolInitF
{
@ -432,8 +487,6 @@ class PString : public PBasicType
public:
PString();
virtual int GetRegType() const;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const override;
@ -463,6 +516,26 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSpriteID : public PInt
{
DECLARE_CLASS(PSpriteID, PInt);
public:
PSpriteID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PTextureID : public PInt
{
DECLARE_CLASS(PTextureID, PInt);
public:
PTextureID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PColor : public PInt
{
DECLARE_CLASS(PColor, PInt);
@ -470,45 +543,48 @@ public:
PColor();
};
// Pointers -----------------------------------------------------------------
class PStatePointer : public PBasicType
class PStateLabel : public PInt
{
DECLARE_CLASS(PStatePointer, PBasicType);
DECLARE_CLASS(PStateLabel, PInt);
public:
PStatePointer();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetRegType() const;
PStateLabel();
};
// Pointers -----------------------------------------------------------------
class PPointer : public PBasicType
{
DECLARE_CLASS(PPointer, PBasicType);
HAS_OBJECT_POINTERS;
public:
PPointer(PType *pointsat);
PPointer();
PPointer(PType *pointsat, bool isconst = false);
PType *PointedType;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetRegType() const;
bool IsConst;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
protected:
PPointer();
void SetOps();
};
class PStatePointer : public PPointer
{
DECLARE_CLASS(PStatePointer, PPointer);
public:
PStatePointer();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PClassPointer : public PPointer
{
DECLARE_CLASS(PClassPointer, PPointer);
@ -518,6 +594,9 @@ public:
class PClass *ClassRestriction;
// this is only here to block PPointer's implementation
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override {}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
@ -532,13 +611,12 @@ class PField : public PSymbol
DECLARE_CLASS(PField, PSymbol);
HAS_OBJECT_POINTERS
public:
PField(FName name, PType *type) : PSymbol(name), Offset(0), Type(type), Flags(0) {}
PField(FName name, PType *type, DWORD flags) : PSymbol(name), Offset(0), Type(type), Flags(flags) {}
PField(FName name, PType *type, DWORD flags, unsigned offset) : PSymbol(name), Offset(offset), Type(type), Flags(flags) {}
PField(FName name, PType *type, DWORD flags = 0, size_t offset = 0, int bitvalue = 0);
unsigned int Offset;
size_t Offset;
PType *Type;
DWORD Flags;
int BitValue;
protected:
PField();
};
@ -576,22 +654,12 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) const override;
protected:
PArray();
};
// A vector is an array with extra operations.
class PVector : public PArray
{
DECLARE_CLASS(PVector, PArray);
HAS_OBJECT_POINTERS;
public:
PVector(unsigned int size);
protected:
PVector();
};
class PDynArray : public PCompoundType
{
DECLARE_CLASS(PDynArray, PCompoundType);
@ -630,14 +698,17 @@ public:
PStruct(FName name, PTypeBase *outer);
TArray<PField *> Fields;
bool HasNativeFields;
virtual PField *AddField(FName name, PType *type, DWORD flags=0);
virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = 0);
size_t PropagateMark();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) const override;
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const;
@ -645,6 +716,15 @@ protected:
PStruct();
};
// a native struct will always be abstract and cannot be instantiated. All variables are references.
// In addition, native structs can have methods (but no virtual ones.)
class PNativeStruct : public PStruct
{
DECLARE_CLASS(PNativeStruct, PStruct);
public:
PNativeStruct(FName name = NAME_None);
};
class PPrototype : public PCompoundType
{
DECLARE_CLASS(PPrototype, PCompoundType);
@ -668,19 +748,28 @@ class PFunction : public PSymbol
public:
struct Variant
{
//PPrototype *Proto;
PPrototype *Proto;
VMFunction *Implementation;
TArray<DWORD> ArgFlags; // Should be the same length as Proto->ArgumentTypes
TArray<FName> ArgNames; // we need the names to access them later when the function gets compiled.
uint32_t Flags;
int UseFlags;
PStruct *SelfClass;
};
TArray<Variant> Variants;
DWORD Flags;
PStruct *OwningClass = nullptr;
unsigned AddVariant(PPrototype *proto, TArray<DWORD> &argflags, VMFunction *impl);
unsigned AddVariant(PPrototype *proto, TArray<DWORD> &argflags, TArray<FName> &argnames, VMFunction *impl, int flags, int useflags);
int GetImplicitArgs()
{
if (Variants[0].Flags & VARF_Action) return 3;
else if (Variants[0].Flags & VARF_Method) return 1;
return 0;
}
size_t PropagateMark();
PFunction(FName name) : PSymbol(name), Flags(0) {}
PFunction() : PSymbol(NAME_None), Flags(0) {}
PFunction(PStruct *owner = nullptr, FName name = NAME_None) : PSymbol(name), OwningClass(owner) {}
};
// Meta-info for every class derived from DObject ---------------------------
@ -691,16 +780,17 @@ enum
};
class PClassClass;
class PClass : public PStruct
class PClass : public PNativeStruct
{
DECLARE_CLASS(PClass, PStruct);
DECLARE_CLASS(PClass, PNativeStruct);
HAS_OBJECT_POINTERS;
protected:
// We unravel _WITH_META here just as we did for PType.
enum { MetaClassNum = CLASSREG_PClassClass };
TArray<FTypeAndOffset> SpecialInits;
virtual void Derive(PClass *newclass);
void Derive(PClass *newclass, FName name);
void InitializeSpecials(void *addr) const;
void SetSuper();
public:
typedef PClassClass MetaClass;
MetaClass *GetClass() const;
@ -709,8 +799,10 @@ public:
void WriteAllFields(FSerializer &ar, const void *addr) const;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
bool ReadAllFields(FSerializer &ar, void *addr) const;
void InitializeDefaults();
int FindVirtualIndex(FName name, PPrototype *proto);
virtual void DeriveData(PClass *newclass);
virtual void DeriveData(PClass *newclass) {}
static void StaticInit();
static void StaticShutdown();
static void StaticBootstrap();
@ -721,6 +813,9 @@ public:
const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default
BYTE *Defaults;
bool bRuntimeClass; // class was defined at run-time, not compile-time
bool bExported; // This type has been declared in a script
bool bDecorateClass; // may be subject to some idiosyncracies due to DECORATE backwards compatibility
TArray<VMFunction*> Virtuals; // virtual function table
void (*ConstructNative)(void *);
@ -764,7 +859,8 @@ public:
static PClassActor *FindActor(const FString &name) { return FindActor(FName(name, true)); }
static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); }
static PClassActor *FindActor(FName name);
PClass *FindClassTentative(FName name, bool fatal = true); // not static!
static VMFunction *FindFunction(FName cls, FName func);
PClass *FindClassTentative(FName name);
static TArray<PClass *> AllClasses;
@ -777,7 +873,7 @@ class PClassType : public PClass
protected:
public:
PClassType();
virtual void Derive(PClass *newclass);
virtual void DeriveData(PClass *newclass);
PClass *TypeTableType; // The type to use for hashing into the type table
};
@ -799,17 +895,6 @@ inline PClass::MetaClass *PClass::GetClass() const
return static_cast<MetaClass *>(DObject::GetClass());
}
// A class that hasn't had its parent class defined yet ---------------------
class PClassWaitingForParent : public PClass
{
DECLARE_CLASS(PClassWaitingForParent, PClass);
public:
PClassWaitingForParent(FName myname, FName parentname);
FName ParentName;
};
// Type tables --------------------------------------------------------------
struct FTypeTable
@ -832,20 +917,20 @@ struct FTypeTable
extern FTypeTable TypeTable;
// Returns a type from the TypeTable. Will create one if it isn't present.
PVector *NewVector(unsigned int size);
PMap *NewMap(PType *keytype, PType *valuetype);
PArray *NewArray(PType *type, unsigned int count);
PDynArray *NewDynArray(PType *type);
PPointer *NewPointer(PType *type);
PPointer *NewPointer(PType *type, bool isconst = false);
PClassPointer *NewClassPointer(PClass *restrict);
PClassWaitingForParent *NewUnknownClass(FName myname, FName parentname);
PEnum *NewEnum(FName name, PTypeBase *outer);
PStruct *NewStruct(FName name, PTypeBase *outer);
PNativeStruct *NewNativeStruct(FName name, PTypeBase *outer);
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
// Built-in types -----------------------------------------------------------
extern PErrorType *TypeError;
extern PErrorType *TypeAuto;
extern PVoidType *TypeVoid;
extern PInt *TypeSInt8, *TypeUInt8;
extern PInt *TypeSInt16, *TypeUInt16;
@ -856,7 +941,15 @@ extern PString *TypeString;
extern PName *TypeName;
extern PSound *TypeSound;
extern PColor *TypeColor;
extern PTextureID *TypeTextureID;
extern PSpriteID *TypeSpriteID;
extern PStruct *TypeVector2;
extern PStruct *TypeVector3;
extern PStruct *TypeColorStruct;
extern PStruct *TypeStringStruct;
extern PStatePointer *TypeState;
extern PStateLabel *TypeStateLabel;
extern PPointer *TypeNullPtr;
// A constant value ---------------------------------------------------------

View file

@ -56,6 +56,12 @@ public:
strncpy (m_Message, message, MAX_ERRORTEXT-1);
m_Message[MAX_ERRORTEXT-1] = '\0';
}
void AppendMessage(const char *message)
{
size_t len = strlen(m_Message);
strncpy(m_Message + len, message, MAX_ERRORTEXT - 1 - len);
m_Message[MAX_ERRORTEXT - 1] = '\0';
}
const char *GetMessage (void) const
{
if (m_Message[0] != '\0')
@ -64,7 +70,7 @@ public:
return NULL;
}
private:
protected:
char m_Message[MAX_ERRORTEXT];
};

View file

@ -49,57 +49,6 @@
class PClassActor;
typedef TMap<int, PClassActor *> FClassMap;
// Since this file is included by everything, it seems an appropriate place
// to check the NOASM/USEASM macros.
// There are three assembly-related macros:
//
// NOASM - Assembly code is disabled
// X86_ASM - Using ia32 assembly code
// X64_ASM - Using amd64 assembly code
//
// Note that these relate only to using the pure assembly code. Inline
// assembly may still be used without respect to these macros, as
// deemed appropriate.
#ifndef NOASM
// Select the appropriate type of assembly code to use.
#if defined(_M_IX86) || defined(__i386__)
#define X86_ASM
#ifdef X64_ASM
#undef X64_ASM
#endif
#elif defined(_M_X64) || defined(__amd64__)
#define X64_ASM
#ifdef X86_ASM
#undef X86_ASM
#endif
#else
#define NOASM
#endif
#endif
#ifdef NOASM
// Ensure no assembly macros are defined if NOASM is defined.
#ifdef X86_ASM
#undef X86_ASM
#endif
#ifdef X64_ASM
#undef X64_ASM
#endif
#endif
#if defined(_MSC_VER)
#define NOVTABLE __declspec(novtable)
@ -265,12 +214,14 @@ char ( &_ArraySizeHelper( T (&array)[N] ))[N];
#ifdef __MACH__
#define SECTION_AREG "__DATA,areg"
#define SECTION_CREG "__DATA,creg"
#define SECTION_FREG "__DATA,freg"
#define SECTION_GREG "__DATA,greg"
#define SECTION_MREG "__DATA,mreg"
#define SECTION_YREG "__DATA,yreg"
#else
#define SECTION_AREG "areg"
#define SECTION_CREG "creg"
#define SECTION_FREG "freg"
#define SECTION_GREG "greg"
#define SECTION_MREG "mreg"
#define SECTION_YREG "yreg"

View file

@ -32,7 +32,7 @@
#include "serializer.h"
#include "doomstat.h"
IMPLEMENT_CLASS (DSectorEffect)
IMPLEMENT_CLASS(DSectorEffect, false, false)
DSectorEffect::DSectorEffect ()
: DThinker(STAT_SECTOREFFECT)
@ -72,9 +72,11 @@ void DSectorEffect::Serialize(FSerializer &arc)
arc("sector", m_Sector);
}
IMPLEMENT_POINTY_CLASS (DMover)
DECLARE_POINTER(interpolation)
END_POINTERS
IMPLEMENT_CLASS(DMover, false, true)
IMPLEMENT_POINTERS_START(DMover)
IMPLEMENT_POINTER(interpolation)
IMPLEMENT_POINTERS_END
DMover::DMover ()
{
@ -107,9 +109,7 @@ void DMover::StopInterpolation(bool force)
}
}
IMPLEMENT_CLASS (DMovingFloor)
IMPLEMENT_CLASS(DMovingFloor, false, false)
DMovingFloor::DMovingFloor ()
{
@ -122,7 +122,7 @@ DMovingFloor::DMovingFloor (sector_t *sector)
interpolation = sector->SetInterpolation(sector_t::FloorMove, true);
}
IMPLEMENT_CLASS (DMovingCeiling)
IMPLEMENT_CLASS(DMovingCeiling, false, false)
DMovingCeiling::DMovingCeiling ()
{

View file

@ -12,7 +12,7 @@ public:
void Serialize(FSerializer &arc);
void Destroy();
void Destroy() override;
sector_t *GetSector() const { return m_Sector; }
@ -35,7 +35,7 @@ protected:
DMover ();
void Serialize(FSerializer &arc);
void Destroy();
void Destroy() override;
};
class DMovingFloor : public DMover

View file

@ -40,6 +40,7 @@
#include "doomerrors.h"
#include "serializer.h"
#include "d_player.h"
#include "virtual.h"
static cycle_t ThinkCycles;
@ -47,7 +48,7 @@ extern cycle_t BotSupportCycles;
extern cycle_t ActionCycles;
extern int BotWTG;
IMPLEMENT_CLASS (DThinker)
IMPLEMENT_CLASS(DThinker, false, false)
DThinker *NextToThink;
@ -55,6 +56,12 @@ FThinkerList DThinker::Thinkers[MAX_STATNUM+2];
FThinkerList DThinker::FreshThinkers[MAX_STATNUM+1];
bool DThinker::bSerialOverride = false;
//==========================================================================
//
//
//
//==========================================================================
void FThinkerList::AddTail(DThinker *thinker)
{
assert(thinker->PrevThinker == NULL && thinker->NextThinker == NULL);
@ -79,6 +86,12 @@ void FThinkerList::AddTail(DThinker *thinker)
GC::WriteBarrier(Sentinel, thinker);
}
//==========================================================================
//
//
//
//==========================================================================
DThinker *FThinkerList::GetHead() const
{
if (Sentinel == NULL || Sentinel->NextThinker == Sentinel)
@ -89,6 +102,12 @@ DThinker *FThinkerList::GetHead() const
return Sentinel->NextThinker;
}
//==========================================================================
//
//
//
//==========================================================================
DThinker *FThinkerList::GetTail() const
{
if (Sentinel == NULL || Sentinel->PrevThinker == Sentinel)
@ -98,11 +117,23 @@ DThinker *FThinkerList::GetTail() const
return Sentinel->PrevThinker;
}
//==========================================================================
//
//
//
//==========================================================================
bool FThinkerList::IsEmpty() const
{
return Sentinel == NULL || Sentinel->NextThinker == NULL;
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::SaveList(FSerializer &arc, DThinker *node)
{
if (node != NULL)
@ -233,6 +264,12 @@ void DThinker::Destroy ()
Super::Destroy();
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::Remove()
{
if (this == NextToThink)
@ -253,14 +290,53 @@ void DThinker::Remove()
PrevThinker = NULL;
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::PostBeginPlay ()
{
}
DEFINE_ACTION_FUNCTION(DThinker, PostBeginPlay)
{
PARAM_SELF_PROLOGUE(DThinker);
self->PostBeginPlay();
return 0;
}
void DThinker::CallPostBeginPlay()
{
IFVIRTUAL(DThinker, PostBeginPlay)
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
}
else
{
PostBeginPlay();
}
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::PostSerialize()
{
}
//==========================================================================
//
//
//
//==========================================================================
DThinker *DThinker::FirstThinker (int statnum)
{
DThinker *node;
@ -281,6 +357,12 @@ DThinker *DThinker::FirstThinker (int statnum)
return node;
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::ChangeStatNum (int statnum)
{
FThinkerList *list;
@ -304,7 +386,19 @@ void DThinker::ChangeStatNum (int statnum)
list->AddTail(this);
}
DEFINE_ACTION_FUNCTION(DThinker, ChangeStatNum)
{
PARAM_SELF_PROLOGUE(DThinker);
PARAM_INT(stat);
self->ChangeStatNum(stat);
return 0;
}
//==========================================================================
//
// Mark the first thinker of each list
//
//==========================================================================
void DThinker::MarkRoots()
{
for (int i = 0; i <= MAX_STATNUM; ++i)
@ -315,7 +409,12 @@ void DThinker::MarkRoots()
GC::Mark(Thinkers[MAX_STATNUM+1].Sentinel);
}
//==========================================================================
//
// Destroy every thinker
//
//==========================================================================
void DThinker::DestroyAllThinkers ()
{
int i;
@ -332,6 +431,12 @@ void DThinker::DestroyAllThinkers ()
GC::FullGC();
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::DestroyThinkersInList (FThinkerList &list)
{
if (list.Sentinel != NULL)
@ -346,6 +451,12 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
}
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::RunThinkers ()
{
int i, count;
@ -376,6 +487,12 @@ void DThinker::RunThinkers ()
ThinkCycles.Unclock();
}
//==========================================================================
//
//
//
//==========================================================================
int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
{
int count = 0;
@ -398,7 +515,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
node->Remove();
dest->AddTail(node);
}
node->PostBeginPlay();
node->CallPostBeginPlay();
}
else if (dest != NULL)
{
@ -407,7 +524,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
if (!(node->ObjectFlags & OF_EuthanizeMe))
{ // Only tick thinkers not scheduled for destruction
node->Tick();
node->CallTick();
node->ObjectFlags &= ~OF_JustSpawned;
GC::CheckGC();
}
@ -416,10 +533,40 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
return count;
}
//==========================================================================
//
//
//
//==========================================================================
void DThinker::Tick ()
{
}
DEFINE_ACTION_FUNCTION(DThinker, Tick)
{
PARAM_SELF_PROLOGUE(DThinker);
self->Tick();
return 0;
}
void DThinker::CallTick()
{
IFVIRTUAL(DThinker, Tick)
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
}
else Tick();
}
//==========================================================================
//
//
//
//==========================================================================
size_t DThinker::PropagateMark()
{
// Do not choke on partially initialized objects (as happens when loading a savegame fails)
@ -433,6 +580,12 @@ size_t DThinker::PropagateMark()
return Super::PropagateMark();
}
//==========================================================================
//
//
//
//==========================================================================
FThinkerIterator::FThinkerIterator (const PClass *type, int statnum)
{
if ((unsigned)statnum > MAX_STATNUM)
@ -450,6 +603,12 @@ FThinkerIterator::FThinkerIterator (const PClass *type, int statnum)
m_SearchingFresh = false;
}
//==========================================================================
//
//
//
//==========================================================================
FThinkerIterator::FThinkerIterator (const PClass *type, int statnum, DThinker *prev)
{
if ((unsigned)statnum > MAX_STATNUM)
@ -474,13 +633,25 @@ FThinkerIterator::FThinkerIterator (const PClass *type, int statnum, DThinker *p
}
}
//==========================================================================
//
//
//
//==========================================================================
void FThinkerIterator::Reinit ()
{
m_CurrThinker = DThinker::Thinkers[m_Stat].GetHead();
m_SearchingFresh = false;
}
DThinker *FThinkerIterator::Next ()
//==========================================================================
//
//
//
//==========================================================================
DThinker *FThinkerIterator::Next (bool exact)
{
if (m_ParentType == NULL)
{
@ -496,7 +667,11 @@ DThinker *FThinkerIterator::Next ()
{
DThinker *thinker = m_CurrThinker;
m_CurrThinker = thinker->NextThinker;
if (thinker->IsKindOf(m_ParentType))
if (exact)
{
if (thinker->IsA(m_ParentType)) return thinker;
}
else if (thinker->IsKindOf(m_ParentType))
{
return thinker;
}
@ -521,6 +696,52 @@ DThinker *FThinkerIterator::Next ()
return NULL;
}
//==========================================================================
//
// This is for scripting, which needs the iterator wrapped into an object with the needed functions exported.
// Unfortunately we cannot have templated type conversions in scripts.
//
//==========================================================================
class DThinkerIterator : public DObject, public FThinkerIterator
{
DECLARE_CLASS(DThinkerIterator, DObject)
public:
DThinkerIterator(PClass *cls = nullptr, int statnum = MAX_STATNUM + 1)
: FThinkerIterator(cls, statnum)
{
}
};
IMPLEMENT_CLASS(DThinkerIterator, false, false);
DEFINE_ACTION_FUNCTION(DThinkerIterator, Create)
{
PARAM_PROLOGUE;
PARAM_CLASS_DEF(type, DThinker);
PARAM_INT_DEF(statnum);
ACTION_RETURN_OBJECT(new DThinkerIterator(type, statnum));
}
DEFINE_ACTION_FUNCTION(DThinkerIterator, Next)
{
PARAM_SELF_PROLOGUE(DThinkerIterator);
ACTION_RETURN_OBJECT(self->Next());
}
DEFINE_ACTION_FUNCTION(DThinkerIterator, Reinit)
{
PARAM_SELF_PROLOGUE(DThinkerIterator);
self->Reinit();
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
ADD_STAT (think)
{
FString out;

View file

@ -66,10 +66,12 @@ class DThinker : public DObject
DECLARE_CLASS (DThinker, DObject)
public:
DThinker (int statnum = STAT_DEFAULT) throw();
void Destroy ();
void Destroy () override;
virtual ~DThinker ();
virtual void Tick ();
void CallTick();
virtual void PostBeginPlay (); // Called just before the first tick
void CallPostBeginPlay();
virtual void PostSerialize();
size_t PropagateMark();
@ -121,7 +123,7 @@ private:
public:
FThinkerIterator (const PClass *type, int statnum=MAX_STATNUM+1);
FThinkerIterator (const PClass *type, int statnum, DThinker *prev);
DThinker *Next ();
DThinker *Next (bool exact = false);
void Reinit ();
};
@ -146,9 +148,9 @@ public:
TThinkerIterator (const char *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum)
{
}
T *Next ()
T *Next (bool exact = false)
{
return static_cast<T *>(FThinkerIterator::Next ());
return static_cast<T *>(FThinkerIterator::Next (exact));
}
};

View file

@ -374,7 +374,7 @@ public:
static FileWriter *Open(const char *filename);
virtual size_t Write(const void *buffer, size_t len);
size_t Printf(const char *fmt, ...);
size_t Printf(const char *fmt, ...) GCCPRINTF(2,3);
protected:

View file

@ -69,6 +69,7 @@
#include "p_setup.h"
#include "p_spec.h"
#include "r_utility.h"
#include "a_ammo.h"
#include "math/cmath.h"
static FRandom pr_script("FScript");
@ -1785,9 +1786,7 @@ public:
void Destroy() { Super::Destroy(); m_Sector->lightingdata=NULL; }
};
IMPLEMENT_CLASS (DLightLevel)
IMPLEMENT_CLASS(DLightLevel, false, false)
void DLightLevel::Serialize(FSerializer &arc)
{
@ -2015,13 +2014,13 @@ void FParser::SF_CeilingTexture(void)
void FParser::SF_ChangeHubLevel(void)
{
I_Error("FS hub system permanently disabled\n");
script_error("FS hub system permanently disabled\n");
}
// for start map: start new game on a particular skill
void FParser::SF_StartSkill(void)
{
I_Error("startskill is not supported by this implementation!\n");
script_error("startskill is not supported by this implementation!\n");
}
//==========================================================================
@ -2977,7 +2976,7 @@ void FParser::SF_ObjAwaken(void)
if(mo)
{
mo->Activate(Script->trigger);
mo->CallActivate(Script->trigger);
}
}
@ -3636,7 +3635,7 @@ void FParser::SF_Pow()
{
if (CheckArgs(2))
{
t_return.setDouble(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
t_return.setDouble(g_pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
}
}

View file

@ -113,7 +113,7 @@ void FParser::NextToken()
}
if(!Section)
{
I_Error("section not found!\n");
script_error("section not found!\n");
return;
}
}
@ -708,6 +708,18 @@ void FParser::EvaluateExpression(svalue_t &result, int start, int stop)
//
//==========================================================================
void FS_Error(const char *error, ...)
{
va_list argptr;
char errortext[MAX_ERRORTEXT];
va_start(argptr, error);
myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr);
throw CFraggleScriptError(errortext);
}
void FParser::ErrorMessage(FString msg)
{
int linenum = 0;
@ -721,7 +733,7 @@ void FParser::ErrorMessage(FString msg)
}
//lineinfo.Format("Script %d, line %d: ", Script->scriptnum, linenum);
I_Error("Script %d, line %d: %s", Script->scriptnum, linenum, msg.GetChars());
FS_Error("Script %d, line %d: %s", Script->scriptnum, linenum, msg.GetChars());
}
//==========================================================================

View file

@ -71,9 +71,11 @@
//
//==========================================================================
IMPLEMENT_POINTY_CLASS(DFsSection)
DECLARE_POINTER(next)
END_POINTERS
IMPLEMENT_CLASS(DFsSection, false, true)
IMPLEMENT_POINTERS_START(DFsSection)
IMPLEMENT_POINTER(next)
IMPLEMENT_POINTERS_END
//==========================================================================
//

View file

@ -75,23 +75,23 @@ AActor *trigger_obj;
//
//==========================================================================
#define DECLARE_16_POINTERS(v, i) \
DECLARE_POINTER(v[i]) \
DECLARE_POINTER(v[i+1]) \
DECLARE_POINTER(v[i+2]) \
DECLARE_POINTER(v[i+3]) \
DECLARE_POINTER(v[i+4]) \
DECLARE_POINTER(v[i+5]) \
DECLARE_POINTER(v[i+6]) \
DECLARE_POINTER(v[i+7]) \
DECLARE_POINTER(v[i+8]) \
DECLARE_POINTER(v[i+9]) \
DECLARE_POINTER(v[i+10]) \
DECLARE_POINTER(v[i+11]) \
DECLARE_POINTER(v[i+12]) \
DECLARE_POINTER(v[i+13]) \
DECLARE_POINTER(v[i+14]) \
DECLARE_POINTER(v[i+15]) \
#define IMPLEMENT_16_POINTERS(v, i) \
IMPLEMENT_POINTER(v[i]) \
IMPLEMENT_POINTER(v[i+1]) \
IMPLEMENT_POINTER(v[i+2]) \
IMPLEMENT_POINTER(v[i+3]) \
IMPLEMENT_POINTER(v[i+4]) \
IMPLEMENT_POINTER(v[i+5]) \
IMPLEMENT_POINTER(v[i+6]) \
IMPLEMENT_POINTER(v[i+7]) \
IMPLEMENT_POINTER(v[i+8]) \
IMPLEMENT_POINTER(v[i+9]) \
IMPLEMENT_POINTER(v[i+10]) \
IMPLEMENT_POINTER(v[i+11]) \
IMPLEMENT_POINTER(v[i+12]) \
IMPLEMENT_POINTER(v[i+13]) \
IMPLEMENT_POINTER(v[i+14]) \
IMPLEMENT_POINTER(v[i+15]) \
//==========================================================================
//
@ -99,30 +99,32 @@ AActor *trigger_obj;
//
//==========================================================================
IMPLEMENT_POINTY_CLASS(DFsScript)
DECLARE_POINTER(parent)
DECLARE_POINTER(trigger)
DECLARE_16_POINTERS(sections, 0)
DECLARE_POINTER(sections[16])
DECLARE_16_POINTERS(variables, 0)
DECLARE_16_POINTERS(children, 0)
DECLARE_16_POINTERS(children, 16)
DECLARE_16_POINTERS(children, 32)
DECLARE_16_POINTERS(children, 48)
DECLARE_16_POINTERS(children, 64)
DECLARE_16_POINTERS(children, 80)
DECLARE_16_POINTERS(children, 96)
DECLARE_16_POINTERS(children, 112)
DECLARE_16_POINTERS(children, 128)
DECLARE_16_POINTERS(children, 144)
DECLARE_16_POINTERS(children, 160)
DECLARE_16_POINTERS(children, 176)
DECLARE_16_POINTERS(children, 192)
DECLARE_16_POINTERS(children, 208)
DECLARE_16_POINTERS(children, 224)
DECLARE_16_POINTERS(children, 240)
DECLARE_POINTER(children[256])
END_POINTERS
IMPLEMENT_CLASS(DFsScript, false, true)
IMPLEMENT_POINTERS_START(DFsScript)
IMPLEMENT_POINTER(parent)
IMPLEMENT_POINTER(trigger)
IMPLEMENT_16_POINTERS(sections, 0)
IMPLEMENT_POINTER(sections[16])
IMPLEMENT_16_POINTERS(variables, 0)
IMPLEMENT_16_POINTERS(children, 0)
IMPLEMENT_16_POINTERS(children, 16)
IMPLEMENT_16_POINTERS(children, 32)
IMPLEMENT_16_POINTERS(children, 48)
IMPLEMENT_16_POINTERS(children, 64)
IMPLEMENT_16_POINTERS(children, 80)
IMPLEMENT_16_POINTERS(children, 96)
IMPLEMENT_16_POINTERS(children, 112)
IMPLEMENT_16_POINTERS(children, 128)
IMPLEMENT_16_POINTERS(children, 144)
IMPLEMENT_16_POINTERS(children, 160)
IMPLEMENT_16_POINTERS(children, 176)
IMPLEMENT_16_POINTERS(children, 192)
IMPLEMENT_16_POINTERS(children, 208)
IMPLEMENT_16_POINTERS(children, 224)
IMPLEMENT_16_POINTERS(children, 240)
IMPLEMENT_POINTER(children[256])
IMPLEMENT_POINTERS_END
//==========================================================================
//
@ -249,7 +251,7 @@ void DFsScript::ParseScript(char *position)
FParser parse(this);
parse.Run(position, data, data + len);
}
catch (CRecoverableError &err)
catch (CFraggleScriptError &err)
{
Printf ("%s\n", err.GetMessage());
}
@ -267,12 +269,14 @@ void DFsScript::ParseScript(char *position)
//
//==========================================================================
IMPLEMENT_POINTY_CLASS(DRunningScript)
DECLARE_POINTER(prev)
DECLARE_POINTER(next)
DECLARE_POINTER(trigger)
DECLARE_16_POINTERS(variables, 0)
END_POINTERS
IMPLEMENT_CLASS(DRunningScript, false, true)
IMPLEMENT_POINTERS_START(DRunningScript)
IMPLEMENT_POINTER(prev)
IMPLEMENT_POINTER(next)
IMPLEMENT_POINTER(trigger)
IMPLEMENT_16_POINTERS(variables, 0)
IMPLEMENT_POINTERS_END
//==========================================================================
//
@ -375,10 +379,13 @@ void DRunningScript::Serialize(FSerializer &arc)
// The main thinker
//
//==========================================================================
IMPLEMENT_POINTY_CLASS(DFraggleThinker)
DECLARE_POINTER(RunningScripts)
DECLARE_POINTER(LevelScript)
END_POINTERS
IMPLEMENT_CLASS(DFraggleThinker, false, true)
IMPLEMENT_POINTERS_START(DFraggleThinker)
IMPLEMENT_POINTER(RunningScripts)
IMPLEMENT_POINTER(LevelScript)
IMPLEMENT_POINTERS_END
TObjPtr<DFraggleThinker> DFraggleThinker::ActiveThinker;

View file

@ -41,12 +41,22 @@
#include "p_lnspec.h"
#include "m_fixed.h"
#include "actor.h"
#include "doomerrors.h"
#ifdef _MSC_VER
// This pragma saves 8kb of wasted code.
#pragma pointers_to_members( full_generality, single_inheritance )
#endif
class CFraggleScriptError : public CDoomError
{
public:
CFraggleScriptError() : CDoomError() {}
CFraggleScriptError(const char *message) : CDoomError(message) {}
};
class DRunningScript;
@ -337,7 +347,7 @@ public:
DFsScript();
~DFsScript();
void Destroy();
void Destroy() override;
void Serialize(FSerializer &ar);
DFsVariable *NewVariable(const char *name, int vtype);
@ -652,7 +662,7 @@ class DRunningScript : public DObject
public:
DRunningScript(AActor *trigger=NULL, DFsScript *owner = NULL, int index = 0) ;
void Destroy();
void Destroy() override;
void Serialize(FSerializer &arc);
TObjPtr<DFsScript> script;
@ -687,7 +697,7 @@ public:
bool nocheckposition;
DFraggleThinker();
void Destroy();
void Destroy() override;
void Serialize(FSerializer & arc);
@ -708,7 +718,7 @@ public:
#include "t_fs.h"
void script_error(const char *s, ...);
void script_error(const char *s, ...) GCCPRINTF(1,2);
void FS_EmulateCmd(char * string);
extern AActor *trigger_obj;

View file

@ -179,10 +179,12 @@ AActor* actorvalue(const svalue_t &svalue)
//
//==========================================================================
IMPLEMENT_POINTY_CLASS(DFsVariable)
DECLARE_POINTER (next)
DECLARE_POINTER (actor)
END_POINTERS
IMPLEMENT_CLASS(DFsVariable, false, true)
IMPLEMENT_POINTERS_START(DFsVariable)
IMPLEMENT_POINTER(next)
IMPLEMENT_POINTER(actor)
IMPLEMENT_POINTERS_END
//==========================================================================
//

View file

@ -1,30 +0,0 @@
/*
#include "actor.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
DEFINE_ACTION_FUNCTION(AActor, A_BspiAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
// launch a missile
P_SpawnMissile (self, self->target, PClass::FindActor("ArachnotronPlasma"));
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BabyMetal)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "baby/walk", 1, ATTN_IDLE);
A_Chase (stack, self);
return 0;
}

View file

@ -1,160 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "s_sound.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
//
// PIT_VileCheck
// Detect a corpse that could be raised.
//
void A_Fire(AActor *self, double height);
//
// A_VileStart
//
DEFINE_ACTION_FUNCTION(AActor, A_VileStart)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_VOICE, "vile/start", 1, ATTN_NORM);
return 0;
}
//
// A_Fire
// Keep fire in front of player unless out of sight
//
DEFINE_ACTION_FUNCTION(AActor, A_StartFire)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "vile/firestrt", 1, ATTN_NORM);
A_Fire (self, 0);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "vile/firecrkl", 1, ATTN_NORM);
A_Fire (self, 0);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire)
{
PARAM_ACTION_PROLOGUE;
PARAM_FLOAT_OPT(height) { height = 0; }
A_Fire(self, height);
return 0;
}
void A_Fire(AActor *self, double height)
{
AActor *dest;
dest = self->tracer;
if (dest == NULL || self->target == NULL)
return;
// don't move it if the vile lost sight
if (!P_CheckSight (self->target, dest, 0) )
return;
DVector3 newpos = dest->Vec3Angle(24., dest->Angles.Yaw, height);
self->SetOrigin(newpos, true);
}
//
// A_VileTarget
// Spawn the hellfire
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(fire, AActor) { fire = PClass::FindActor("ArchvileFire"); }
AActor *fog;
if (!self->target)
return 0;
A_FaceTarget (self);
fog = Spawn (fire, self->target->Pos(), ALLOW_REPLACE);
self->tracer = fog;
fog->target = self;
fog->tracer = self->target;
A_Fire(fog, 0);
return 0;
}
//
// A_VileAttack
//
// A_VileAttack flags
#define VAF_DMGTYPEAPPLYTODIRECT 1
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
{
PARAM_ACTION_PROLOGUE;
PARAM_SOUND_OPT (snd) { snd = "vile/stop"; }
PARAM_INT_OPT (dmg) { dmg = 20; }
PARAM_INT_OPT (blastdmg) { blastdmg = 70; }
PARAM_INT_OPT (blastrad) { blastrad = 70; }
PARAM_FLOAT_OPT (thrust) { thrust = 1; }
PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; }
PARAM_INT_OPT (flags) { flags = 0; }
AActor *fire, *target;
if (NULL == (target = self->target))
return 0;
A_FaceTarget (self);
if (!P_CheckSight (self, target, 0) )
return 0;
S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);
int newdam;
if (flags & VAF_DMGTYPEAPPLYTODIRECT)
newdam = P_DamageMobj (target, self, self, dmg, dmgtype);
else
newdam = P_DamageMobj (target, self, self, dmg, NAME_None);
P_TraceBleed (newdam > 0 ? newdam : dmg, target);
fire = self->tracer;
if (fire != NULL)
{
// move the fire between the vile and the player
DVector3 pos = target->Vec3Angle(-24., self->Angles.Yaw, 0);
fire->SetOrigin (pos, true);
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
}
if (!(target->flags7 & MF7_DONTTHRUST))
{
target->Vel.Z = thrust * 1000 / MAX(1, target->Mass);
}
return 0;
}

View file

@ -1,325 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "p_local.h"
#include "p_enemy.h"
#include "s_sound.h"
#include "statnums.h"
#include "a_specialspot.h"
#include "thingdef/thingdef.h"
#include "doomstat.h"
#include "g_level.h"
*/
static FRandom pr_brainscream ("BrainScream");
static FRandom pr_brainexplode ("BrainExplode");
static FRandom pr_spawnfly ("SpawnFly");
DEFINE_ACTION_FUNCTION(AActor, A_BrainAwake)
{
PARAM_ACTION_PROLOGUE;
// killough 3/26/98: only generates sound now
S_Sound (self, CHAN_VOICE, "brain/sight", 1, ATTN_NONE);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BrainPain)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_VOICE, "brain/pain", 1, ATTN_NONE);
return 0;
}
static void BrainishExplosion (const DVector3 &pos)
{
AActor *boom = Spawn("Rocket", pos, NO_REPLACE);
if (boom != NULL)
{
boom->DeathSound = "misc/brainexplode";
boom->Vel.Z = pr_brainscream() /128.;
PClassActor *cls = PClass::FindActor("BossBrain");
if (cls != NULL)
{
FState *state = cls->FindState(NAME_Brainexplode);
if (state != NULL)
boom->SetState (state);
}
boom->effects = 0;
boom->SetDamage(0); // disables collision detection which is not wanted here
boom->tics -= pr_brainscream() & 7;
if (boom->tics < 1)
boom->tics = 1;
}
}
DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
{
PARAM_ACTION_PROLOGUE;
for (double x = -196; x < +320; x += 8)
{
// (1 / 512.) is actually what the original value of 128 did, even though it probably meant 128 map units.
BrainishExplosion(self->Vec2OffsetZ(x, -320, (1 / 512.) + pr_brainexplode() * 2));
}
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode)
{
PARAM_ACTION_PROLOGUE;
double x = pr_brainexplode.Random2() / 32.;
DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2);
BrainishExplosion(pos);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
{
PARAM_ACTION_PROLOGUE;
// [RH] If noexit, then don't end the level.
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
return 0;
// New dmflag: Kill all boss spawned monsters before ending the level.
if (dmflags2 & DF2_KILLBOSSMONST)
{
int count; // Repeat until we have no more boss-spawned monsters.
do // (e.g. Pain Elementals can spawn more to kill upon death.)
{
TThinkerIterator<AActor> it;
AActor *mo;
count = 0;
while ((mo = it.Next()))
{
if (mo->health > 0 && mo->flags4 & MF4_BOSSSPAWNED)
{
P_DamageMobj(mo, self, self, mo->health, NAME_None,
DMG_NO_ARMOR|DMG_FORCED|DMG_THRUSTLESS|DMG_NO_FACTOR);
count++;
}
}
} while (count != 0);
}
G_ExitLevel (0, false);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
DSpotState *state = DSpotState::GetSpotState();
AActor *targ;
AActor *spit;
bool isdefault = false;
// shoot a cube at current target
targ = state->GetNextInList(PClass::FindActor("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));
if (targ != NULL)
{
if (spawntype == NULL)
{
spawntype = PClass::FindActor("SpawnShot");
isdefault = true;
}
// spawn brain missile
spit = P_SpawnMissile (self, targ, spawntype);
if (spit != NULL)
{
// Boss cubes should move freely to their destination so it's
// probably best to disable all collision detection for them.
if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION;
spit->target = targ;
spit->master = self;
// [RH] Do this correctly for any trajectory. Doom would divide by 0
// if the target had the same y coordinate as the spitter.
if (spit->Vel.X == 0 && spit->Vel.Y == 0)
{
spit->special2 = 0;
}
else if (fabs(spit->Vel.Y) > fabs(spit->Vel.X))
{
spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y);
}
else
{
spit->special2 = int((targ->X() - self->X()) / spit->Vel.X);
}
// [GZ] Calculates when the projectile will have reached destination
spit->special2 += level.maptime;
spit->flags6 |= MF6_BOSSCUBE;
}
if (!isdefault)
{
S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE);
}
else
{
// compatibility fallback
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
}
}
return 0;
}
static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound)
{
AActor *newmobj;
AActor *fog;
AActor *eye = self->master; // The eye is the spawnshot's master, not the target!
AActor *targ = self->target; // Unlike other projectiles, the target is the intended destination.
int r;
// [GZ] Should be more viable than a countdown...
if (self->special2 != 0)
{
if (self->special2 > level.maptime)
return; // still flying
}
else
{
if (self->reactiontime == 0 || --self->reactiontime != 0)
return; // still flying
}
if (spawntype != NULL)
{
fog = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE);
if (fog != NULL) S_Sound (fog, CHAN_BODY, sound, 1, ATTN_NORM);
}
FName SpawnName;
DDropItem *di; // di will be our drop item list iterator
DDropItem *drop; // while drop stays as the reference point.
int n = 0;
// First see if this cube has its own actor list
drop = self->GetDropItems();
// If not, then default back to its master's list
if (drop == NULL && eye != NULL)
drop = eye->GetDropItems();
if (drop != NULL)
{
for (di = drop; di != NULL; di = di->Next)
{
if (di->Name != NAME_None)
{
if (di->Amount < 0)
{
di->Amount = 1; // default value is -1, we need a positive value.
}
n += di->Amount; // this is how we can weight the list.
}
}
di = drop;
n = pr_spawnfly(n);
while (n >= 0)
{
if (di->Name != NAME_None)
{
n -= di->Amount; // logically, none of the -1 values have survived by now.
}
if ((di->Next != NULL) && (n >= 0))
{
di = di->Next;
}
else
{
n = -1;
}
}
SpawnName = di->Name;
}
if (SpawnName == NAME_None)
{
// Randomly select monster to spawn.
r = pr_spawnfly ();
// Probability distribution (kind of :),
// decreasing likelihood.
if (r < 50) SpawnName = "DoomImp";
else if (r < 90) SpawnName = "Demon";
else if (r < 120) SpawnName = "Spectre";
else if (r < 130) SpawnName = "PainElemental";
else if (r < 160) SpawnName = "Cacodemon";
else if (r < 162) SpawnName = "Archvile";
else if (r < 172) SpawnName = "Revenant";
else if (r < 192) SpawnName = "Arachnotron";
else if (r < 222) SpawnName = "Fatso";
else if (r < 246) SpawnName = "HellKnight";
else SpawnName = "BaronOfHell";
}
spawntype = PClass::FindActor(SpawnName);
if (spawntype != NULL)
{
newmobj = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE);
if (newmobj != NULL)
{
// Make the new monster hate what the boss eye hates
if (eye != NULL)
{
newmobj->CopyFriendliness (eye, false);
}
// Make it act as if it was around when the player first made noise
// (if the player has made noise).
newmobj->LastHeard = newmobj->Sector->SoundTarget;
if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true, NULL))
{
newmobj->SetState (newmobj->SeeState);
}
if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
{
// telefrag anything in this spot
P_TeleportMove (newmobj, newmobj->Pos(), true);
}
newmobj->flags4 |= MF4_BOSSSPAWNED;
}
}
// remove self (i.e., cube).
self->Destroy ();
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
FSoundID sound;
if (spawntype != NULL)
{
sound = GetDefaultByType(spawntype)->SeeSound;
}
else
{
spawntype = PClass::FindActor("SpawnFire");
sound = "brain/spawn";
}
SpawnFly(self, spawntype, sound);
return 0;
}
// travelling cube sound
DEFINE_ACTION_FUNCTION(AActor, A_SpawnSound)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "brain/cube", 1, ATTN_IDLE);
SpawnFly(self, PClass::FindActor("SpawnFire"), "brain/spawn");
return 0;
}

View file

@ -1,23 +0,0 @@
static FRandom pr_bruisattack ("BruisAttack");
DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
if (self->CheckMeleeRange ())
{
int damage = (pr_bruisattack()%8+1)*10;
S_Sound (self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
// launch a missile
P_SpawnMissile (self, self->target, PClass::FindActor("BaronBall"));
return 0;
}

View file

@ -1,35 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "s_sound.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_headattack ("HeadAttack");
DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = (pr_headattack()%6+1)*10;
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
// launch a missile
P_SpawnMissile (self, self->target, PClass::FindActor("CacodemonBall"));
return 0;
}

View file

@ -1,29 +0,0 @@
/*
#include "actor.h"
#include "p_local.h"
#include "s_sound.h"
#include "p_enemy.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
DEFINE_ACTION_FUNCTION(AActor, A_CyberAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
P_SpawnMissile (self, self->target, PClass::FindActor("Rocket"));
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_Hoof)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "cyber/hoof", 1, ATTN_IDLE);
A_Chase (stack, self);
return 0;
}

View file

@ -1,29 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_sargattack ("SargAttack");
DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = ((pr_sargattack()%10)+1)*4;
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
}
return 0;
}

View file

@ -1,43 +0,0 @@
#ifndef __A_DOOMGLOBAL_H__
#define __A_DOOMGLOBAL_H__
#include "info.h"
class AScriptedMarine : public AActor
{
DECLARE_CLASS (AScriptedMarine, AActor)
public:
enum EMarineWeapon
{
WEAPON_Dummy,
WEAPON_Fist,
WEAPON_BerserkFist,
WEAPON_Chainsaw,
WEAPON_Pistol,
WEAPON_Shotgun,
WEAPON_SuperShotgun,
WEAPON_Chaingun,
WEAPON_RocketLauncher,
WEAPON_PlasmaRifle,
WEAPON_Railgun,
WEAPON_BFG
};
void Activate (AActor *activator);
void Deactivate (AActor *activator);
void BeginPlay ();
void Tick ();
void SetWeapon (EMarineWeapon);
void SetSprite (PClassActor *source);
void Serialize(FSerializer &arc);
int CurrentWeapon;
protected:
bool GetWeaponStates(int weap, FState *&melee, FState *&missile);
int SpriteOverride;
};
#endif //__A_DOOMGLOBAL_H__

View file

@ -1,38 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_troopattack ("TroopAttack");
//
// A_TroopAttack
//
DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = (pr_troopattack()%8+1)*3;
S_Sound (self, CHAN_WEAPON, "imp/melee", 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
// launch a missile
P_SpawnMissile (self, self->target, PClass::FindActor("DoomImpBall"));
return 0;
}

View file

@ -1,59 +0,0 @@
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "p_spec.h"
#include "a_sharedglobal.h"
#include "m_random.h"
#include "gi.h"
#include "doomstat.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
#include "p_enemy.h"
#include "a_doomglobal.h"
#include "a_specialspot.h"
#include "templates.h"
#include "m_bbox.h"
#include "portal.h"
#include "d_player.h"
#include "p_maputl.h"
#include "serializer.h"
#include "g_shared/a_pickups.h"
// Include all the other Doom stuff here to reduce compile time
#include "a_arachnotron.cpp"
#include "a_archvile.cpp"
#include "a_bossbrain.cpp"
#include "a_bruiser.cpp"
#include "a_cacodemon.cpp"
#include "a_cyberdemon.cpp"
#include "a_demon.cpp"
#include "a_doomimp.cpp"
#include "a_doomweaps.cpp"
#include "a_fatso.cpp"
#include "a_keen.cpp"
#include "a_lostsoul.cpp"
#include "a_painelemental.cpp"
#include "a_possessed.cpp"
#include "a_revenant.cpp"
#include "a_spidermaster.cpp"
#include "a_scriptedmarine.cpp"
// The barrel of green goop ------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
{
PARAM_ACTION_PROLOGUE;
if (dmflags2 & DF2_BARRELS_RESPAWN)
{
self->Height = self->GetDefault()->Height;
self->renderflags |= RF_INVISIBLE;
self->flags &= ~MF_SOLID;
}
else
{
self->Destroy ();
}
return 0;
}

View file

@ -1,782 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "s_sound.h"
#include "m_random.h"
#include "a_pickups.h"
#include "d_player.h"
#include "p_pspr.h"
#include "p_local.h"
#include "gstrings.h"
#include "p_effect.h"
#include "gi.h"
#include "templates.h"
#include "thingdef/thingdef.h"
#include "doomstat.h"
*/
static FRandom pr_punch ("Punch");
static FRandom pr_saw ("Saw");
static FRandom pr_fireshotgun2 ("FireSG2");
static FRandom pr_fireplasma ("FirePlasma");
static FRandom pr_firerail ("FireRail");
static FRandom pr_bfgspray ("BFGSpray");
static FRandom pr_oldbfg ("OldBFG");
//
// A_Punch
//
DEFINE_ACTION_FUNCTION(AActor, A_Punch)
{
PARAM_ACTION_PROLOGUE;
DAngle angle;
int damage;
DAngle pitch;
FTranslatedLineTarget t;
if (self->player != NULL)
{
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
}
damage = (pr_punch()%10+1)<<1;
if (self->FindInventory<APowerStrength>())
damage *= 10;
angle = self->Angles.Yaw + pr_punch.Random2() * (5.625 / 256);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &t);
// turn to face target
if (t.linetarget)
{
S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
self->Angles.Yaw = t.angleFromSource;
}
return 0;
}
//
// A_FirePistol
//
DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
{
PARAM_ACTION_PROLOGUE;
bool accurate;
if (self->player != nullptr)
{
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
P_SetPsprite(self->player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
}
self->player->mo->PlayAttacking2 ();
accurate = !self->player->refire;
}
else
{
accurate = true;
}
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
P_GunShot (self, accurate, PClass::FindActor(NAME_BulletPuff), P_BulletSlope (self));
return 0;
}
//
// A_Saw
//
enum SAW_Flags
{
SF_NORANDOM = 1,
SF_RANDOMLIGHTMISS = 2,
SF_RANDOMLIGHTHIT = 4,
SF_NOUSEAMMOMISS = 8,
SF_NOUSEAMMO = 16,
SF_NOPULLIN = 32,
SF_NOTURN = 64,
SF_STEALARMOR = 128,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
{
PARAM_ACTION_PROLOGUE;
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_FLOAT_OPT (range) { range = 0; }
PARAM_ANGLE_OPT (spread_xy) { spread_xy = 2.8125; }
PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; }
PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; }
PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; }
PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; }
DAngle angle;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
int actualdamage;
if (NULL == (player = self->player))
{
return 0;
}
if (pufftype == NULL)
{
pufftype = PClass::FindActor(NAME_BulletPuff);
}
if (damage == 0)
{
damage = 2;
}
if (!(flags & SF_NORANDOM))
{
damage *= (pr_saw()%10+1);
}
if (range == 0)
{
range = SAWRANGE;
}
angle = self->Angles.Yaw + spread_xy * (pr_saw.Random2() / 255.);
slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.);
AWeapon *weapon = self->player->ReadyWeapon;
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
P_LineAttack (self, angle, range, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage);
if (!t.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 && !(t.linetarget->flags5 & MF5_DONTDRAIN))
{
if (flags & SF_STEALARMOR)
{
if (armorbonustype == NULL)
{
armorbonustype = dyn_cast<ABasicArmorBonus::MetaClass>(PClass::FindClass("ArmorBonus"));
}
if (armorbonustype != NULL)
{
assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)));
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype));
armorbonus->SaveAmount = int(armorbonus->SaveAmount * actualdamage * lifesteal);
armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
armorbonus->flags |= MF_DROPPED;
armorbonus->ClearCounters();
if (!armorbonus->CallTryPickup (self))
{
armorbonus->Destroy ();
}
}
}
else
{
P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax);
}
}
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
// turn to face target
if (!(flags & SF_NOTURN))
{
DAngle anglediff = deltaangle(self->Angles.Yaw, t.angleFromSource);
if (anglediff < 0.0)
{
if (anglediff < -4.5)
self->Angles.Yaw = angle + 90.0 / 21;
else
self->Angles.Yaw -= 4.5;
}
else
{
if (anglediff > 4.5)
self->Angles.Yaw = angle - 90.0 / 21;
else
self->Angles.Yaw += 4.5;
}
}
if (!(flags & SF_NOPULLIN))
self->flags |= MF_JUSTATTACKED;
return 0;
}
//
// A_FireShotgun
//
DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
{
PARAM_ACTION_PROLOGUE;
int i;
player_t *player;
if (nullptr == (player = self->player))
{
return 0;
}
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
}
player->mo->PlayAttacking2 ();
DAngle pitch = P_BulletSlope (self);
for (i = 0; i < 7; i++)
{
P_GunShot (self, false, PClass::FindActor(NAME_BulletPuff), pitch);
}
return 0;
}
//
// A_FireShotgun2
//
DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
{
PARAM_ACTION_PROLOGUE;
int i;
DAngle angle;
int damage;
player_t *player;
if (nullptr == (player = self->player))
{
return 0;
}
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2))
return 0;
P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
}
player->mo->PlayAttacking2 ();
DAngle pitch = P_BulletSlope (self);
for (i=0 ; i<20 ; i++)
{
damage = 5*(pr_fireshotgun2()%3+1);
angle = self->Angles.Yaw + pr_fireshotgun2.Random2() * (11.25 / 256);
// Doom adjusts the bullet slope by shifting a random number [-255,255]
// left 5 places. At 2048 units away, this means the vertical position
// of the shot can deviate as much as 255 units from nominal. So using
// some simple trigonometry, that means the vertical angle of the shot
// can deviate by as many as ~7.097 degrees or ~84676099 BAMs.
P_LineAttack (self,
angle,
PLAYERMISSILERANGE,
pitch + pr_fireshotgun2.Random2() * (7.097 / 256), damage,
NAME_Hitscan, NAME_BulletPuff);
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_OpenShotgun2)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_LoadShotgun2)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);
A_ReFire (self);
return 0;
}
//------------------------------------------------------------------------------------
//
// Setting a random flash like some of Doom's weapons can easily crash when the
// definition is overridden incorrectly so let's check that the state actually exists.
// Be aware though that this will not catch all DEHACKED related problems. But it will
// find all DECORATE related ones.
//
//------------------------------------------------------------------------------------
void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int index)
{
PClassActor *cls = weapon->GetClass();
while (cls != RUNTIME_CLASS(AWeapon))
{
if (flashstate >= cls->OwnedStates && flashstate < cls->OwnedStates + cls->NumOwnedStates)
{
// The flash state belongs to this class.
// Now let's check if the actually wanted state does also
if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates)
{
// we're ok so set the state
P_SetPsprite(player, PSP_FLASH, flashstate + index, true);
return;
}
else
{
// oh, no! The state is beyond the end of the state table so use the original flash state.
P_SetPsprite(player, PSP_FLASH, flashstate, true);
return;
}
}
// try again with parent class
cls = static_cast<PClassActor *>(cls->ParentClass);
}
// if we get here the state doesn't seem to belong to any class in the inheritance chain
// This can happen with Dehacked if the flash states are remapped.
// The only way to check this would be to go through all Dehacked modifiable actors, convert
// their states into a single flat array and find the correct one.
// Rather than that, just check to make sure it belongs to something.
if (FState::StaticFindStateOwner(flashstate + index) == NULL)
{ // Invalid state. With no index offset, it should at least be valid.
index = 0;
}
P_SetPsprite(player, PSP_FLASH, flashstate + index, true);
}
//
// A_FireCGun
//
DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
{
PARAM_ACTION_PROLOGUE;
player_t *player;
if (self == nullptr || nullptr == (player = self->player))
{
return 0;
}
AWeapon *weapon = player->ReadyWeapon;
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
FState *flash = weapon->FindState(NAME_Flash);
if (flash != nullptr)
{
// [RH] Fix for Sparky's messed-up Dehacked patch! Blargh!
FState * atk = weapon->FindState(NAME_Fire);
int theflash = clamp (int(player->GetPSprite(PSP_WEAPON)->GetState() - atk), 0, 1);
if (flash[theflash].sprite != flash->sprite)
{
theflash = 0;
}
P_SetSafeFlash (weapon, player, flash, theflash);
}
}
player->mo->PlayAttacking2 ();
P_GunShot (self, !player->refire, PClass::FindActor(NAME_BulletPuff), P_BulletSlope (self));
return 0;
}
//
// A_FireMissile
//
DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
{
PARAM_ACTION_PROLOGUE;
player_t *player;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
}
P_SpawnPlayerMissile (self, PClass::FindActor("Rocket"));
return 0;
}
//
// A_FireSTGrenade: not exactly backported from ST, but should work the same
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(grenade, AActor) { grenade = PClass::FindActor("Grenade"); }
player_t *player;
if (grenade == NULL)
return 0;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
// Temporarily raise the pitch to send the grenade slightly upwards
DAngle SavedPlayerPitch = self->Angles.Pitch;
self->Angles.Pitch -= 6.328125; //(1152 << F RACBITS);
P_SpawnPlayerMissile(self, grenade);
self->Angles.Pitch = SavedPlayerPitch;
return 0;
}
//
// A_FirePlasma
//
DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma)
{
PARAM_ACTION_PROLOGUE;
player_t *player;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
FState *flash = weapon->FindState(NAME_Flash);
if (flash != NULL)
{
P_SetSafeFlash(weapon, player, flash, (pr_fireplasma()&1));
}
}
P_SpawnPlayerMissile (self, PClass::FindActor("PlasmaBall"));
return 0;
}
//
// [RH] A_FireRailgun
//
static void FireRailgun(AActor *self, int offset_xy, bool fromweapon)
{
int damage;
player_t *player;
if (NULL == (player = self->player))
{
return;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && fromweapon)
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return;
FState *flash = weapon->FindState(NAME_Flash);
if (flash != NULL)
{
P_SetSafeFlash(weapon, player, flash, (pr_firerail()&1));
}
}
damage = deathmatch ? 100 : 150;
FRailParams p;
p.source = self;
p.damage = damage;
p.offset_xy = offset_xy;
P_RailAttack (&p);
}
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgun)
{
PARAM_ACTION_PROLOGUE;
FireRailgun(self, 0, ACTION_CALL_FROM_PSPRITE());
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunRight)
{
PARAM_ACTION_PROLOGUE;
FireRailgun(self, 10, ACTION_CALL_FROM_PSPRITE());
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunLeft)
{
PARAM_ACTION_PROLOGUE;
FireRailgun(self, -10, ACTION_CALL_FROM_PSPRITE());
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_RailWait)
{
// Okay, this was stupid. Just use a NULL function instead of this.
return 0;
}
//
// A_FireBFG
//
DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
{
PARAM_ACTION_PROLOGUE;
player_t *player;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, deh.BFGCells))
return 0;
}
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->Angles.Yaw, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
return 0;
}
//
// A_BFGSpray
// Spawn a BFG explosion on every monster in view
//
enum BFG_Flags
{
BFGF_HURTSOURCE = 1,
BFGF_MISSILEORIGIN = 2,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (spraytype, AActor) { spraytype = NULL; }
PARAM_INT_OPT (numrays) { numrays = 0; }
PARAM_INT_OPT (damagecnt) { damagecnt = 0; }
PARAM_ANGLE_OPT (angle) { angle = 0.; }
PARAM_FLOAT_OPT (distance) { distance = 0; }
PARAM_ANGLE_OPT (vrange) { vrange = 0.; }
PARAM_INT_OPT (defdamage) { defdamage = 0; }
PARAM_INT_OPT (flags) { flags = 0; }
int i;
int j;
int damage;
DAngle an;
FTranslatedLineTarget t;
AActor *originator;
if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
if (numrays <= 0) numrays = 40;
if (damagecnt <= 0) damagecnt = 15;
if (angle == 0) angle = 90.;
if (distance <= 0) distance = 16 * 64;
if (vrange == 0) vrange = 32.;
// [RH] Don't crash if no target
if (!self->target)
return 0;
// [XA] Set the originator of the rays to the projectile (self) if
// the new flag is set, else set it to the player (self->target)
originator = (flags & BFGF_MISSILEORIGIN) ? self : (AActor *)(self->target);
// offset angles from its attack angle
for (i = 0; i < numrays; i++)
{
an = self->Angles.Yaw - angle / 2 + angle / numrays*i;
P_AimLineAttack(originator, an, distance, &t, vrange);
if (t.linetarget != NULL)
{
AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->Height / 4), ALLOW_REPLACE);
int dmgFlags = 0;
FName dmgType = NAME_BFGSplash;
if (spray != NULL)
{
if ((spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies()) ||
(!(flags & BFGF_HURTSOURCE) && self->target == t.linetarget)) // [XA] Don't hit oneself unless we say so.
{
spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them.
continue;
}
if (spray->flags5 & MF5_PUFFGETSOWNER) spray->target = self->target;
if (spray->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL;
if (spray->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA;
dmgType = spray->DamageType;
}
if (defdamage == 0)
{
damage = 0;
for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1;
}
else
{
// if this is used, damagecnt will be ignored
damage = defdamage;
}
int newdam = P_DamageMobj(t.linetarget, originator, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees);
P_TraceBleed(newdam > 0 ? newdam : damage, &t, self);
}
}
return 0;
}
//
// A_BFGsound
//
DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM);
return 0;
}
//
// A_FireOldBFG
//
// This function emulates Doom's Pre-Beta BFG
// By Lee Killough 6/6/98, 7/11/98, 7/19/98, 8/20/98
//
// This code may not be used in other mods without appropriate credit given.
// Code leeches will be telefragged.
DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
{
PARAM_ACTION_PROLOGUE;
PClassActor *plasma[] = { PClass::FindActor("PlasmaBall1"), PClass::FindActor("PlasmaBall2") };
AActor * mo = NULL;
player_t *player;
bool doesautoaim = false;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (!ACTION_CALL_FROM_PSPRITE()) weapon = NULL;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return 0;
doesautoaim = !(weapon->WeaponFlags & WIF_NOAUTOAIM);
weapon->WeaponFlags |= WIF_NOAUTOAIM; // No autoaiming that gun
}
self->player->extralight = 2;
// Save values temporarily
DAngle SavedPlayerAngle = self->Angles.Yaw;
DAngle SavedPlayerPitch = self->Angles.Pitch;
for (int i = 0; i < 2; i++) // Spawn two plasma balls in sequence
{
self->Angles.Yaw += ((pr_oldbfg()&127) - 64) * (90./768);
self->Angles.Pitch += ((pr_oldbfg()&127) - 64) * (90./640);
mo = P_SpawnPlayerMissile (self, plasma[i]);
// Restore saved values
self->Angles.Yaw = SavedPlayerAngle;
self->Angles.Pitch = SavedPlayerPitch;
}
if (doesautoaim && weapon != NULL)
{ // Restore autoaim setting
weapon->WeaponFlags &= ~WIF_NOAUTOAIM;
}
return 0;
}

View file

@ -1,177 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
//
// Mancubus attack,
// firing three missiles in three different directions?
// Doesn't look like it.
//
#define FATSPREAD (90./8)
DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
{
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
// Change direction to ...
self->Angles.Yaw += FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw += FATSPREAD;
missile->VelFromAngle();
}
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
// Now here choose opposite deviation.
self->Angles.Yaw -= FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw -= FATSPREAD*2;
missile->VelFromAngle();
}
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw -= FATSPREAD/2;
missile->VelFromAngle();
}
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw += FATSPREAD/2;
missile->VelFromAngle();
}
return 0;
}
//
// killough 9/98: a mushroom explosion effect, sorta :)
// Original idea: Linguica
//
enum
{
MSF_Standard = 0,
MSF_Classic = 1,
MSF_DontHurt = 2,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
PARAM_INT_OPT (n) { n = 0; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_FLOAT_OPT (vrange) { vrange = 4; }
PARAM_FLOAT_OPT (hrange) { hrange = 0.5; }
int i, j;
if (n == 0)
{
n = self->GetMissileDamage(0, 1);
}
if (spawntype == NULL)
{
spawntype = PClass::FindActor("FatShot");
}
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE);
P_CheckSplash(self, 128.);
// Now launch mushroom cloud
AActor *target = Spawn("Mapspot", self->Pos(), NO_REPLACE); // We need something to aim at.
AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self;
target->Height = self->Height;
for (i = -n; i <= n; i += 8)
{
for (j = -n; j <= n; j += 8)
{
AActor *mo;
target->SetXYZ(
self->X() + i, // Aim in many directions from source
self->Y() + j,
self->Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high
if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options
(flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM)))
{ // Use old function for MBF compatibility
mo = P_OldSpawnMissile (self, master, target, spawntype);
}
else // Use normal function
{
mo = P_SpawnMissile(self, target, spawntype, master);
}
if (mo != NULL)
{ // Slow it down a bit
mo->Vel *= hrange;
mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity
}
}
}
target->Destroy();
return 0;
}

View file

@ -1,42 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "p_spec.h"
#include "p_enemy.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
//
// A_KeenDie
// DOOM II special, map 32.
// Uses special tag 666 by default.
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie)
{
PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT(doortag) { doortag = 666; }
A_Unblock(self, false);
// scan the remaining thinkers to see if all Keens are dead
AActor *other;
TThinkerIterator<AActor> iterator;
const PClass *matchClass = self->GetClass ();
while ( (other = iterator.Next ()) )
{
if (other != self && other->health > 0 && other->IsA (matchClass))
{
// other Keen not dead
return 0;
}
}
EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2., 0, 0, 0);
return 0;
}

View file

@ -1,86 +0,0 @@
/*
#include "templates.h"
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gi.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
FRandom pr_oldsoul ("BetaLostSoul");
//
// SkullAttack
// Fly at the player like a missile.
//
void A_SkullAttack(AActor *self, double speed)
{
AActor *dest;
if (!self->target)
return;
dest = self->target;
self->flags |= MF_SKULLFLY;
S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
self->VelFromAngle(speed);
self->Vel.Z = (dest->Center() - self->Z()) / self->DistanceBySpeed(dest, speed);
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
{
PARAM_ACTION_PROLOGUE;
PARAM_FLOAT_OPT(speed) { speed = SKULLSPEED; }
if (speed <= 0)
speed = SKULLSPEED;
A_SkullAttack(self, speed);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack)
{
PARAM_ACTION_PROLOGUE;
int damage;
if (!self || !self->target || self->target->GetSpecies() == self->GetSpecies())
return 0;
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget(self);
damage = (pr_oldsoul()%8+1)*self->GetMissileDamage(0,1);
P_DamageMobj(self->target, self, self, damage, NAME_None);
return 0;
}
//==========================================================================
//
// CVAR transsouls
//
// How translucent things drawn with STYLE_SoulTrans are. Normally, only
// Lost Souls have this render style, but a dehacked patch could give other
// things this style. Values less than 0.25 will automatically be set to
// 0.25 to ensure some degree of visibility. Likewise, values above 1.0 will
// be set to 1.0, because anything higher doesn't make sense.
//
//==========================================================================
CUSTOM_CVAR (Float, transsouls, 0.75f, CVAR_ARCHIVE)
{
if (self < 0.25f)
{
self = 0.25f;
}
else if (self > 1.f)
{
self = 1.f;
}
}

View file

@ -1,194 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "p_enemy.h"
#include "p_local.h"
#include "a_action.h"
#include "templates.h"
#include "m_bbox.h"
#include "thingdef/thingdef.h"
#include "doomstat.h"
*/
enum PA_Flags
{
PAF_NOSKULLATTACK = 1,
PAF_AIMFACING = 2,
PAF_NOTARGET = 4,
};
//
// A_PainShootSkull
// Spawn a lost soul and launch it at the target
//
void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1)
{
AActor *other;
double prestep;
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
assert(spawntype != NULL);
if (self->DamageType == NAME_Massacre) return;
// [RH] check to make sure it's not too close to the ceiling
if (self->Top() + 8 > self->ceilingz)
{
if (self->flags & MF_FLOAT)
{
self->Vel.Z -= 2;
self->flags |= MF_INFLOAT;
self->flags4 |= MF4_VFRICTION;
}
return;
}
// [RH] make this optional
if (limit == -1 && (i_compatflags & COMPATF_LIMITPAIN))
limit = 21;
if (limit)
{
// count total number of skulls currently on the level
// if there are already 21 skulls on the level, don't spit another one
int count = limit;
FThinkerIterator iterator (spawntype);
DThinker *othink;
while ( (othink = iterator.Next ()) )
{
if (--count == 0)
return;
}
}
// okay, there's room for another one
prestep = 4 + (self->radius + GetDefaultByType(spawntype)->radius) * 1.5;
// NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive.
DVector2 dist = Angle.ToVector(prestep);
DVector3 pos = self->Vec3Offset(dist.X, dist.Y, 8., true);
DVector3 src = self->Pos();
for (int i = 0; i < 2; i++)
{
// Check whether the Lost Soul is being fired through a 1-sided // phares
// wall or an impassible line, or a "monsters can't cross" line.// |
// If it is, then we don't allow the spawn. // V
FBoundingBox box(MIN(src.X, pos.X), MIN(src.Y, pos.Y), MAX(src.X, pos.X), MAX(src.Y, pos.Y));
FBlockLinesIterator it(box);
line_t *ld;
bool inportal = false;
while ((ld = it.Next()))
{
if (ld->isLinePortal() && i == 0)
{
if (P_PointOnLineSidePrecise(src, ld) == 0 &&
P_PointOnLineSidePrecise(pos, ld) == 1)
{
// crossed a portal line from front to back, we need to repeat the check on the other side as well.
inportal = true;
}
}
else if (!(ld->flags & ML_TWOSIDED) ||
(ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING)))
{
if (box.inRange(ld))
{
if (P_PointOnLineSidePrecise(src, ld) != P_PointOnLineSidePrecise(pos, ld))
return; // line blocks trajectory // ^
}
}
}
if (!inportal) break;
// recalculate position and redo the check on the other side of the portal
pos = self->Vec3Offset(dist.X, dist.Y, 8.);
src.X = pos.X - dist.X;
src.Y = pos.Y - dist.Y;
}
other = Spawn (spawntype, pos, ALLOW_REPLACE);
// Check to see if the new Lost Soul's z value is above the
// ceiling of its new sector, or below the floor. If so, kill it.
if (other->Top() > other->Sector->HighestCeilingAt(other) ||
other->Z() < other->Sector->LowestFloorAt(other))
{
// kill it immediately
P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);// ^
return; // |
} // phares
// Check for movements.
if (!P_CheckPosition (other, other->Pos()))
{
// kill it immediately
P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);
return;
}
// [RH] Lost souls hate the same things as their pain elementals
other->CopyFriendliness (self, !(flags & PAF_NOTARGET));
if (!(flags & PAF_NOSKULLATTACK))
A_SkullAttack(other, SKULLSPEED);
}
//
// A_PainAttack
// Spawn a lost soul and launch it at the target
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
PARAM_ANGLE_OPT (angle) { angle = 0.; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_INT_OPT (limit) { limit = -1; }
if (!(flags & PAF_AIMFACING))
A_FaceTarget (self);
A_PainShootSkull (self, self->Angles.Yaw + angle, spawntype, flags, limit);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
if (!self->target)
return 0;
A_FaceTarget (self);
A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype);
A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
if (self->target != NULL && self->IsFriend(self->target))
{ // And I thought you were my friend!
self->flags &= ~MF_FRIENDLY;
}
A_Unblock(self, true);
A_PainShootSkull (self, self->Angles.Yaw + 90, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 180, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 270, spawntype);
return 0;
}

View file

@ -1,134 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_posattack ("PosAttack");
static FRandom pr_sposattack ("SPosAttack");
static FRandom pr_cposattack ("CPosAttack");
static FRandom pr_cposrefire ("CPosRefire");
//
// A_PosAttack
//
DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
{
PARAM_ACTION_PROLOGUE;
int damage;
DAngle angle;
DAngle slope;
if (!self->target)
return 0;
A_FaceTarget (self);
angle = self->Angles.Yaw;
slope = P_AimLineAttack (self, angle, MISSILERANGE);
S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM);
angle += pr_posattack.Random2() * (22.5 / 256);
damage = ((pr_posattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;
}
static void A_SPosAttack2 (AActor *self)
{
int i;
DAngle bangle;
DAngle slope;
A_FaceTarget (self);
bangle = self->Angles.Yaw;
slope = P_AimLineAttack (self, bangle, MISSILERANGE);
for (i=0 ; i<3 ; i++)
{
DAngle angle = bangle + pr_sposattack.Random2() * (22.5 / 256);
int damage = ((pr_sposattack()%5)+1)*3;
P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
}
}
DEFINE_ACTION_FUNCTION(AActor, A_SPosAttackUseAtkSound)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_SPosAttack2 (self);
return 0;
}
// This version of the function, which uses a hard-coded sound, is
// meant for Dehacked only.
DEFINE_ACTION_FUNCTION(AActor, A_SPosAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
S_Sound (self, CHAN_WEAPON, "shotguy/attack", 1, ATTN_NORM);
A_SPosAttack2 (self);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
{
PARAM_ACTION_PROLOGUE;
DAngle angle;
DAngle bangle;
int damage;
DAngle slope;
if (!self->target)
return 0;
// [RH] Andy Baker's stealth monsters
if (self->flags & MF_STEALTH)
{
self->visdir = 1;
}
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
bangle = self->Angles.Yaw;
slope = P_AimLineAttack (self, bangle, MISSILERANGE);
angle = bangle + pr_cposattack.Random2() * (22.5 / 256);
damage = ((pr_cposattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire)
{
PARAM_ACTION_PROLOGUE;
// keep firing unless target got out of sight
A_FaceTarget (self);
if (pr_cposrefire() < 40)
return 0;
if (!self->target
|| P_HitFriend (self)
|| self->target->health <= 0
|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
{
self->SetState (self->SeeState);
}
return 0;
}

View file

@ -1,152 +0,0 @@
/*
#include "templates.h"
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
*/
static FRandom pr_tracer ("Tracer");
static FRandom pr_skelfist ("SkelFist");
//
// A_SkelMissile
//
DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile)
{
PARAM_ACTION_PROLOGUE;
AActor *missile;
if (!self->target)
return 0;
A_FaceTarget (self);
self->AddZ(16.);
missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer"));
self->AddZ(-16.);
if (missile != NULL)
{
missile->SetOrigin(missile->Vec3Offset(missile->Vel.X, missile->Vel.Y, 0.), false);
missile->tracer = self->target;
}
return 0;
}
#define TRACEANGLE (16.875)
DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
{
PARAM_ACTION_PROLOGUE;
double dist;
double slope;
AActor *dest;
AActor *smoke;
// killough 1/18/98: this is why some missiles do not have smoke
// and some do. Also, internal demos start at random gametics, thus
// the bug in which revenants cause internal demos to go out of sync.
//
// killough 3/6/98: fix revenant internal demo bug by subtracting
// levelstarttic from gametic:
//
// [RH] level.time is always 0-based, so nothing special to do here.
if (level.time & 3)
return 0;
// spawn a puff of smoke behind the rocket
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->Angles.Yaw, self->Angles.Yaw, 3);
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE);
smoke->Vel.Z = 1.;
smoke->tics -= pr_tracer()&3;
if (smoke->tics < 1)
smoke->tics = 1;
// adjust direction
dest = self->tracer;
if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest))
return 0;
// change angle
DAngle exact = self->AngleTo(dest);
DAngle diff = deltaangle(self->Angles.Yaw, exact);
if (diff < 0)
{
self->Angles.Yaw -= TRACEANGLE;
if (deltaangle(self->Angles.Yaw, exact) > 0)
self->Angles.Yaw = exact;
}
else if (diff > 0)
{
self->Angles.Yaw += TRACEANGLE;
if (deltaangle(self->Angles.Yaw, exact) < 0.)
self->Angles.Yaw = exact;
}
self->VelFromAngle();
if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{
// change slope
dist = self->DistanceBySpeed(dest, self->Speed);
if (dest->Height >= 56.)
{
slope = (dest->Z() + 40. - self->Z()) / dist;
}
else
{
slope = (dest->Z() + self->Height*(2./3) - self->Z()) / dist;
}
if (slope < self->Vel.Z)
self->Vel.Z -= 1. / 8;
else
self->Vel.Z += 1. / 8;
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_SkelWhoosh)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "skeleton/swing", 1, ATTN_NORM);
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_SkelFist)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
return 0;
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = ((pr_skelfist()%10)+1)*6;
S_Sound (self, CHAN_WEAPON, "skeleton/melee", 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
}
return 0;
}

View file

@ -1,654 +0,0 @@
/*
#include "actor.h"
#include "p_enemy.h"
#include "a_action.h"
#include "m_random.h"
#include "p_local.h"
#include "a_doomglobal.h"
#include "s_sound.h"
#include "r_data/r_translate.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
*/
#define MARINE_PAIN_CHANCE 160
static FRandom pr_m_refire ("SMarineRefire");
static FRandom pr_m_punch ("SMarinePunch");
static FRandom pr_m_gunshot ("SMarineGunshot");
static FRandom pr_m_saw ("SMarineSaw");
static FRandom pr_m_fireshotgun2 ("SMarineFireSSG");
IMPLEMENT_CLASS (AScriptedMarine)
void AScriptedMarine::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
auto def = (AScriptedMarine*)GetDefault();
arc.Sprite("spriteoverride", SpriteOverride, &def->SpriteOverride)
("currentweapon", CurrentWeapon, def->CurrentWeapon);
}
void AScriptedMarine::Activate (AActor *activator)
{
if (flags2 & MF2_DORMANT)
{
flags2 &= ~MF2_DORMANT;
tics = 1;
}
}
void AScriptedMarine::Deactivate (AActor *activator)
{
if (!(flags2 & MF2_DORMANT))
{
flags2 |= MF2_DORMANT;
tics = -1;
}
}
bool AScriptedMarine::GetWeaponStates(int weap, FState *&melee, FState *&missile)
{
static ENamedName WeaponNames[] =
{
NAME_None,
NAME_Fist,
NAME_Berserk,
NAME_Chainsaw,
NAME_Pistol,
NAME_Shotgun,
NAME_SSG,
NAME_Chaingun,
NAME_Rocket,
NAME_Plasma,
NAME_Railgun,
NAME_BFG
};
if (weap < WEAPON_Dummy || weap > WEAPON_BFG) weap = WEAPON_Dummy;
melee = FindState(NAME_Melee, WeaponNames[weap], true);
missile = FindState(NAME_Missile, WeaponNames[weap], true);
return melee != NULL || missile != NULL;
}
void AScriptedMarine::BeginPlay ()
{
Super::BeginPlay ();
// Set the current weapon
for(int i=WEAPON_Dummy; i<=WEAPON_BFG; i++)
{
FState *melee, *missile;
if (GetWeaponStates(i, melee, missile))
{
if (melee == MeleeState && missile == MissileState)
{
CurrentWeapon = i;
}
}
}
}
void AScriptedMarine::Tick ()
{
Super::Tick ();
// Override the standard sprite, if desired
if (SpriteOverride != 0 && sprite == SpawnState->sprite)
{
sprite = SpriteOverride;
}
if (special1 != 0)
{
if (CurrentWeapon == WEAPON_SuperShotgun)
{ // Play SSG reload sounds
int ticks = level.maptime - special1;
if (ticks < 47)
{
switch (ticks)
{
case 14:
S_Sound (this, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM);
break;
case 28:
S_Sound (this, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM);
break;
case 41:
S_Sound (this, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);
break;
}
}
else
{
special1 = 0;
}
}
else
{ // Wait for a long refire time
if (level.maptime >= special1)
{
special1 = 0;
}
else
{
flags |= MF_JUSTATTACKED;
}
}
}
}
//============================================================================
//
// A_M_Refire
//
//============================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
{
PARAM_ACTION_PROLOGUE;
PARAM_BOOL_OPT(ignoremissile) { ignoremissile = false; }
if (self->target == NULL || self->target->health <= 0)
{
if (self->MissileState && pr_m_refire() < 160)
{ // Look for a new target most of the time
if (P_LookForPlayers (self, true, NULL) && P_CheckMissileRange (self))
{ // Found somebody new and in range, so don't stop shooting
return 0;
}
}
self->SetState (self->state + 1);
return 0;
}
if (((ignoremissile || self->MissileState == NULL) && !self->CheckMeleeRange ()) ||
!P_CheckSight (self, self->target) ||
pr_m_refire() < 4) // Small chance of stopping even when target not dead
{
self->SetState (self->state + 1);
}
return 0;
}
//============================================================================
//
// A_M_SawRefire
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_SawRefire)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL || self->target->health <= 0)
{
self->SetState (self->state + 1);
return 0;
}
if (!self->CheckMeleeRange ())
{
self->SetState (self->state + 1);
}
return 0;
}
//============================================================================
//
// A_MarineNoise
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_MarineNoise)
{
PARAM_ACTION_PROLOGUE;
if (static_cast<AScriptedMarine *>(self)->CurrentWeapon == AScriptedMarine::WEAPON_Chainsaw)
{
S_Sound (self, CHAN_WEAPON, "weapons/sawidle", 1, ATTN_NORM);
}
return 0;
}
//============================================================================
//
// A_MarineChase
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_MarineChase)
{
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_MarineNoise, self);
A_Chase (stack, self);
return 0;
}
//============================================================================
//
// A_MarineLook
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_MarineLook)
{
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_MarineNoise, self);
CALL_ACTION(A_Look, self);
return 0;
}
//============================================================================
//
// A_M_Saw
//
//============================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
{
PARAM_ACTION_PROLOGUE;
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; }
if (self->target == NULL)
return 0;
if (pufftype == NULL)
{
pufftype = PClass::FindActor(NAME_BulletPuff);
}
if (damage == 0)
{
damage = 2;
}
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
DAngle angle;
FTranslatedLineTarget t;
damage *= (pr_m_saw()%10+1);
angle = self->Angles.Yaw + pr_m_saw.Random2() * (5.625 / 256);
P_LineAttack (self, angle, SAWRANGE,
P_AimLineAttack (self, angle, SAWRANGE), damage,
NAME_Melee, pufftype, false, &t);
if (!t.linetarget)
{
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
return 0;
}
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
// turn to face target
angle = t.angleFromSource;
DAngle anglediff = deltaangle(self->Angles.Yaw, angle);
if (anglediff < 0.0)
{
if (anglediff < -4.5)
self->Angles.Yaw = angle + 90.0 / 21;
else
self->Angles.Yaw -= 4.5;
}
else
{
if (anglediff > 4.5)
self->Angles.Yaw = angle - 90.0 / 21;
else
self->Angles.Yaw += 4.5;
}
}
else
{
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
}
//A_Chase (self);
return 0;
}
//============================================================================
//
// A_M_Punch
//
//============================================================================
static void MarinePunch(AActor *self, int damagemul)
{
DAngle angle;
int damage;
DAngle pitch;
FTranslatedLineTarget t;
if (self->target == NULL)
return;
damage = ((pr_m_punch()%10+1) << 1) * damagemul;
A_FaceTarget (self);
angle = self->Angles.Yaw + pr_m_punch.Random2() * (5.625 / 256);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &t);
// turn to face target
if (t.linetarget)
{
S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
self->Angles.Yaw = t.angleFromSource;
}
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
{
PARAM_ACTION_PROLOGUE;
PARAM_INT(mult);
MarinePunch(self, mult);
return 0;
}
//============================================================================
//
// P_GunShot2
//
//============================================================================
void P_GunShot2 (AActor *mo, bool accurate, DAngle pitch, PClassActor *pufftype)
{
DAngle angle;
int damage;
damage = 5*(pr_m_gunshot()%3+1);
angle = mo->Angles.Yaw;
if (!accurate)
{
angle += pr_m_gunshot.Random2() * (5.625 / 256);
}
P_LineAttack (mo, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, pufftype);
}
//============================================================================
//
// A_M_FirePistol
//
//============================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
{
PARAM_ACTION_PROLOGUE;
PARAM_BOOL(accurate);
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE),
PClass::FindActor(NAME_BulletPuff));
return 0;
}
//============================================================================
//
// A_M_FireShotgun
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
{
PARAM_ACTION_PROLOGUE;
DAngle pitch;
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
A_FaceTarget (self);
pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE);
for (int i = 0; i < 7; ++i)
{
P_GunShot2 (self, false, pitch, PClass::FindActor(NAME_BulletPuff));
}
self->special1 = level.maptime + 27;
return 0;
}
//============================================================================
//
// A_M_CheckAttack
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
{
PARAM_ACTION_PROLOGUE;
if (self->special1 != 0 || self->target == NULL)
{
self->SetState (self->FindState("SkipAttack"));
}
else
{
A_FaceTarget (self);
}
return 0;
}
//============================================================================
//
// A_M_FireShotgun2
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
{
PARAM_ACTION_PROLOGUE;
DAngle pitch;
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
A_FaceTarget (self);
pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE);
for (int i = 0; i < 20; ++i)
{
int damage = 5*(pr_m_fireshotgun2()%3+1);
DAngle angle = self->Angles.Yaw + pr_m_fireshotgun2.Random2() * (11.25 / 256);
P_LineAttack (self, angle, MISSILERANGE,
pitch + pr_m_fireshotgun2.Random2() * (7.097 / 256), damage,
NAME_Hitscan, NAME_BulletPuff);
}
self->special1 = level.maptime;
return 0;
}
//============================================================================
//
// A_M_FireCGun
//
//============================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
{
PARAM_ACTION_PROLOGUE;
PARAM_BOOL(accurate);
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE),
PClass::FindActor(NAME_BulletPuff));
return 0;
}
//============================================================================
//
// A_M_FireMissile
//
// Giving a marine a rocket launcher is probably a bad idea unless you pump
// up his health, because he's just as likely to kill himself as he is to
// kill anything else with it.
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
if (self->CheckMeleeRange ())
{ // If too close, punch it
MarinePunch(self, 1);
}
else
{
A_FaceTarget (self);
P_SpawnMissile (self, self->target, PClass::FindActor("Rocket"));
}
return 0;
}
//============================================================================
//
// A_M_FireRailgun
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireRailgun)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
CALL_ACTION(A_MonsterRail, self);
self->special1 = level.maptime + 50;
return 0;
}
//============================================================================
//
// A_M_FirePlasma
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FirePlasma)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
A_FaceTarget (self);
P_SpawnMissile (self, self->target, PClass::FindActor("PlasmaBall"));
self->special1 = level.maptime + 20;
return 0;
}
//============================================================================
//
// A_M_BFGsound
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
if (self->special1 != 0)
{
self->SetState (self->SeeState);
}
else
{
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM);
// Don't interrupt the firing sequence
self->PainChance = 0;
}
return 0;
}
//============================================================================
//
// A_M_FireBFG
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireBFG)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
A_FaceTarget (self);
P_SpawnMissile (self, self->target, PClass::FindActor("BFGBall"));
self->special1 = level.maptime + 30;
self->PainChance = MARINE_PAIN_CHANCE;
return 0;
}
//---------------------------------------------------------------------------
void AScriptedMarine::SetWeapon (EMarineWeapon type)
{
if (GetWeaponStates(type, MeleeState, MissileState))
{
static const char *classes[] = {
"ScriptedMarine",
"MarineFist",
"MarineBerserk",
"MarineChainsaw",
"MarinePistol",
"MarineShotgun",
"MarineSSG",
"MarineChaingun",
"MarineRocket",
"MarinePlasma",
"MarineRailgun",
"MarineBFG"
};
const PClass *cls = PClass::FindClass(classes[type]);
if (cls != NULL)
DecalGenerator = GetDefaultByType(cls)->DecalGenerator;
else
DecalGenerator = NULL;
}
}
void AScriptedMarine::SetSprite (PClassActor *source)
{
if (source == NULL)
{ // A valid actor class wasn't passed, so use the standard sprite
SpriteOverride = sprite = GetClass()->OwnedStates[0].sprite;
// Copy the standard scaling
Scale = GetDefault()->Scale;
}
else
{ // Use the same sprite and scaling the passed class spawns with
SpriteOverride = sprite = GetDefaultByType (source)->SpawnState->sprite;
Scale = GetDefaultByType(source)->Scale;
}
}

View file

@ -1,41 +0,0 @@
/*
#include "templates.h"
#include "actor.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_spidrefire ("SpidRefire");
DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire)
{
PARAM_ACTION_PROLOGUE;
// keep firing unless target got out of sight
A_FaceTarget (self);
if (pr_spidrefire() < 10)
return 0;
if (!self->target
|| P_HitFriend (self)
|| self->target->health <= 0
|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
{
self->SetState (self->SeeState);
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_Metal)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "spider/walk", 1, ATTN_IDLE);
A_Chase (stack, self);
return 0;
}

View file

@ -479,15 +479,15 @@ CCMD (useflechette)
{ // Select from one of arti_poisonbag1-3, whichever the player has
static const ENamedName bagnames[3] =
{
NAME_ArtiPoisonBag3, // use type 3 first because that's the default when the player has none specified.
NAME_ArtiPoisonBag1,
NAME_ArtiPoisonBag2,
NAME_ArtiPoisonBag3
NAME_ArtiPoisonBag2
};
if (who == NULL)
return;
PClassActor *type = GetFlechetteType(who);
PClassActor *type = who->FlechetteType;
if (type != NULL)
{
AInventory *item;
@ -498,7 +498,7 @@ CCMD (useflechette)
}
}
// The default flechette could not be found. Try all 3 types then.
// The default flechette could not be found, or the player had no default. Try all 3 types then.
for (int j = 0; j < 3; ++j)
{
AInventory *item;
@ -1537,6 +1537,36 @@ static FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int sel
return &deathmatchstarts[i];
}
DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart)
{
PARAM_PROLOGUE;
unsigned int selections = deathmatchstarts.Size();
DVector3 pos;
int angle;
if (selections == 0)
{
angle = INT_MAX;
pos = DVector3(0, 0, 0);
}
else
{
unsigned int i = pr_dmspawn() % selections;
angle = deathmatchstarts[i].angle;
pos = deathmatchstarts[i].pos;
}
if (numret > 1)
{
ret[1].SetInt(angle);
numret = 2;
}
if (numret > 0)
{
ret[0].SetVector(pos);
}
return numret;
}
void G_DeathMatchSpawnPlayer (int playernum)
{
unsigned int selections;
@ -1578,6 +1608,7 @@ void G_DeathMatchSpawnPlayer (int playernum)
if (mo != NULL) P_PlayerStartStomp(mo);
}
//
// G_PickPlayerStart
//
@ -1615,6 +1646,24 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags)
return &playerstarts[playernum];
}
DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
{
PARAM_PROLOGUE;
PARAM_INT(playernum);
PARAM_INT_DEF(flags);
auto ps = G_PickPlayerStart(playernum, flags);
if (numret > 1)
{
ret[1].SetInt(ps? ps->angle : 0);
numret = 2;
}
if (numret > 0)
{
ret[0].SetVector(ps ? ps->pos : DVector3(0, 0, 0));
}
return numret;
}
//
// G_QueueBody
//

View file

@ -1,233 +0,0 @@
/*
#include "actor.h"
#include "gi.h"
#include "m_random.h"
#include "s_sound.h"
#include "d_player.h"
#include "a_action.h"
#include "a_pickups.h"
#include "p_local.h"
#include "a_sharedglobal.h"
#include "p_enemy.h"
#include "d_event.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
*/
void P_UpdateBeak (AActor *actor);
static FRandom pr_chickenplayerthink ("ChickenPlayerThink");
static FRandom pr_chicattack ("ChicAttack");
static FRandom pr_feathers ("Feathers");
static FRandom pr_beakatkpl1 ("BeakAtkPL1");
static FRandom pr_beakatkpl2 ("BeakAtkPL2");
class AChickenPlayer : public APlayerPawn
{
DECLARE_CLASS (AChickenPlayer, APlayerPawn)
public:
void MorphPlayerThink ();
};
IMPLEMENT_CLASS(AChickenPlayer)
void AChickenPlayer::MorphPlayerThink ()
{
if (health > 0)
{ // Handle beak movement
P_UpdateBeak (this);
}
if (player->morphTics & 15)
{
return;
}
if (Vel.X == 0 && Vel.Y == 0 && pr_chickenplayerthink () < 160)
{ // Twitch view angle
Angles.Yaw += pr_chickenplayerthink.Random2() * (360. / 256. / 32.);
}
if ((Z() <= floorz) && (pr_chickenplayerthink() < 32))
{ // Jump and noise
Vel.Z += JumpZ;
FState * painstate = FindState(NAME_Pain);
if (painstate != NULL) SetState (painstate);
}
if (pr_chickenplayerthink () < 48)
{ // Just noise
S_Sound (this, CHAN_VOICE, "chicken/active", 1, ATTN_NORM);
}
}
//----------------------------------------------------------------------------
//
// PROC A_ChicAttack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
{
return 0;
}
if (self->CheckMeleeRange())
{
int damage = 1 + (pr_chicattack() & 1);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Feathers
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
{
PARAM_ACTION_PROLOGUE;
int i;
int count;
AActor *mo;
if (self->health > 0)
{ // Pain
count = pr_feathers() < 32 ? 2 : 1;
}
else
{ // Death
count = 5 + (pr_feathers()&3);
}
for (i = 0; i < count; i++)
{
mo = Spawn("Feather", self->PosPlusZ(20.), NO_REPLACE);
mo->target = self;
mo->Vel.X = pr_feathers.Random2() / 256.;
mo->Vel.Y = pr_feathers.Random2() / 256.;
mo->Vel.Z = 1. + pr_feathers() / 128.;
mo->SetState (mo->SpawnState + (pr_feathers()&7));
}
return 0;
}
//---------------------------------------------------------------------------
//
// PROC P_UpdateBeak
//
//---------------------------------------------------------------------------
void P_UpdateBeak (AActor *self)
{
DPSprite *pspr;
if (self->player != nullptr && (pspr = self->player->FindPSprite(PSP_WEAPON)) != nullptr)
{
pspr->y = WEAPONTOP + self->player->chickenPeck / 2;
}
}
//---------------------------------------------------------------------------
//
// PROC A_BeakRaise
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise)
{
PARAM_ACTION_PROLOGUE;
player_t *player;
if (nullptr == (player = self->player))
{
return 0;
}
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP;
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState());
return 0;
}
//----------------------------------------------------------------------------
//
// PROC P_PlayPeck
//
//----------------------------------------------------------------------------
void P_PlayPeck (AActor *chicken)
{
S_Sound (chicken, CHAN_VOICE, "chicken/peck", 1, ATTN_NORM);
}
//----------------------------------------------------------------------------
//
// PROC A_BeakAttackPL1
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
{
PARAM_ACTION_PROLOGUE;
DAngle angle;
int damage;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
if (NULL == (player = self->player))
{
return 0;
}
damage = 1 + (pr_beakatkpl1()&3);
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
if (t.linetarget)
{
player->mo->Angles.Yaw = t.angleFromSource;
}
P_PlayPeck (player->mo);
player->chickenPeck = 12;
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl1() & 7;
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_BeakAttackPL2
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
{
PARAM_ACTION_PROLOGUE;
DAngle angle;
int damage;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
if (NULL == (player = self->player))
{
return 0;
}
damage = pr_beakatkpl2.HitDice (4);
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
if (t.linetarget)
{
player->mo->Angles.Yaw = t.angleFromSource;
}
P_PlayPeck (player->mo);
player->chickenPeck = 12;
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl2()&3;
return 0;
}

View file

@ -1,327 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "s_sound.h"
#include "m_random.h"
#include "a_sharedglobal.h"
#include "gstrings.h"
#include "a_specialspot.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
*/
static FRandom pr_s2fx1 ("S2FX1");
static FRandom pr_scrc1atk ("Srcr1Attack");
static FRandom pr_dst ("D'SparilTele");
static FRandom pr_s2d ("Srcr2Decide");
static FRandom pr_s2a ("Srcr2Attack");
static FRandom pr_bluespark ("BlueSpark");
//----------------------------------------------------------------------------
//
// PROC A_Sor1Pain
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Sor1Pain)
{
PARAM_ACTION_PROLOGUE;
self->special1 = 20; // Number of steps to walk fast
CALL_ACTION(A_Pain, self);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Sor1Chase
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Sor1Chase)
{
PARAM_ACTION_PROLOGUE;
if (self->special1)
{
self->special1--;
self->tics -= 3;
}
A_Chase(stack, self);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Srcr1Attack
//
// Sorcerer demon attack.
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
DAngle angle;
if (!self->target)
{
return 0;
}
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange ())
{
int damage = pr_scrc1atk.HitDice (8);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
PClassActor *fx = PClass::FindActor("SorcererFX1");
if (self->health > (self->SpawnHealth()/3)*2)
{ // Spit one fireball
P_SpawnMissileZ (self, self->Z() + 48, self->target, fx );
}
else
{ // Spit three fireballs
mo = P_SpawnMissileZ (self, self->Z() + 48, self->target, fx);
if (mo != NULL)
{
angle = mo->Angles.Yaw;
P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle - 3, mo->Vel.Z);
P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle + 3, mo->Vel.Z);
}
if (self->health < self->SpawnHealth()/3)
{ // Maybe attack again
if (self->special1)
{ // Just attacked, so don't attack again
self->special1 = 0;
}
else
{ // Set state to attack again
self->special1 = 1;
self->SetState (self->FindState("Missile2"));
}
}
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_SorcererRise
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
self->flags &= ~MF_SOLID;
mo = Spawn("Sorcerer2", self->Pos(), ALLOW_REPLACE);
mo->Translation = self->Translation;
mo->SetState (mo->FindState("Rise"));
mo->Angles.Yaw = self->Angles.Yaw;
mo->CopyFriendliness (self, true);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC P_DSparilTeleport
//
//----------------------------------------------------------------------------
void P_DSparilTeleport (AActor *actor)
{
DVector3 prev;
AActor *mo;
AActor *spot;
DSpotState *state = DSpotState::GetSpotState();
if (state == NULL) return;
spot = state->GetSpotWithMinMaxDistance(PClass::FindActor("BossSpot"), actor->X(), actor->Y(), 128, 0);
if (spot == NULL) return;
prev = actor->Pos();
if (P_TeleportMove (actor, spot->Pos(), false))
{
mo = Spawn("Sorcerer2Telefade", prev, ALLOW_REPLACE);
if (mo) mo->Translation = actor->Translation;
S_Sound (mo, CHAN_BODY, "misc/teleport", 1, ATTN_NORM);
actor->SetState (actor->FindState("Teleport"));
S_Sound (actor, CHAN_BODY, "misc/teleport", 1, ATTN_NORM);
actor->SetZ(actor->floorz);
actor->Angles.Yaw = spot->Angles.Yaw;
actor->Vel.Zero();
}
}
//----------------------------------------------------------------------------
//
// PROC A_Srcr2Decide
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
{
PARAM_ACTION_PROLOGUE;
static const int chance[] =
{
192, 120, 120, 120, 64, 64, 32, 16, 0
};
unsigned int chanceindex = self->health / ((self->SpawnHealth()/8 == 0) ? 1 : self->SpawnHealth()/8);
if (chanceindex >= countof(chance))
{
chanceindex = countof(chance) - 1;
}
if (pr_s2d() < chance[chanceindex])
{
P_DSparilTeleport (self);
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Srcr2Attack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
{
PARAM_ACTION_PROLOGUE;
int chance;
if (!self->target)
{
return 0;
}
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NONE);
if (self->CheckMeleeRange())
{
int damage = pr_s2a.HitDice (20);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
chance = self->health < self->SpawnHealth()/2 ? 96 : 48;
if (pr_s2a() < chance)
{ // Wizard spawners
PClassActor *fx = PClass::FindActor("Sorcerer2FX2");
if (fx)
{
P_SpawnMissileAngle(self, fx, self->Angles.Yaw - 45, 0.5);
P_SpawnMissileAngle(self, fx, self->Angles.Yaw + 45, 0.5);
}
}
else
{ // Blue bolt
P_SpawnMissile (self, self->target, PClass::FindActor("Sorcerer2FX1"));
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_BlueSpark
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
{
PARAM_ACTION_PROLOGUE;
int i;
AActor *mo;
for (i = 0; i < 2; i++)
{
mo = Spawn("Sorcerer2FXSpark", self->Pos(), ALLOW_REPLACE);
mo->Vel.X = pr_bluespark.Random2() / 128.;
mo->Vel.Y = pr_bluespark.Random2() / 128.;
mo->Vel.Z = 1. + pr_bluespark() / 256.;
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_GenWizard
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
if (mo != NULL)
{
mo->AddZ(-mo->GetDefault()->Height / 2, false);
if (!P_TestMobjLocation (mo))
{ // Didn't fit
mo->ClearCounters();
mo->Destroy ();
}
else
{ // [RH] Make the new wizards inherit D'Sparil's target
mo->CopyFriendliness (self->target, true);
self->Vel.Zero();
self->SetState (self->FindState(NAME_Death));
self->flags &= ~MF_MISSILE;
mo->master = self->target;
P_SpawnTeleportFog(self, self->Pos(), false, true);
}
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Sor2DthInit
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit)
{
PARAM_ACTION_PROLOGUE;
self->special1 = 7; // Animation loop counter
P_Massacre (); // Kill monsters early
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_Sor2DthLoop
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthLoop)
{
PARAM_ACTION_PROLOGUE;
if (--self->special1)
{ // Need to loop
self->SetState (self->FindState("DeathLoop"));
}
return 0;
}

View file

@ -1,77 +0,0 @@
/*
#include "info.h"
#include "a_pickups.h"
#include "a_artifacts.h"
#include "gstrings.h"
#include "p_local.h"
#include "s_sound.h"
#include "thingdef/thingdef.h"
*/
// Tome of power ------------------------------------------------------------
class AArtiTomeOfPower : public APowerupGiver
{
DECLARE_CLASS (AArtiTomeOfPower, APowerupGiver)
public:
bool Use (bool pickup);
};
IMPLEMENT_CLASS (AArtiTomeOfPower)
bool AArtiTomeOfPower::Use (bool pickup)
{
if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYTOMEOFPOWER))
{ // Attempt to undo chicken
if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYTOMEOFPOWER))
{ // Failed
if (!(Owner->player->MorphStyle & MORPH_FAILNOTELEFRAG))
{
P_DamageMobj (Owner, NULL, NULL, TELEFRAG_DAMAGE, NAME_Telefrag);
}
}
else
{ // Succeeded
S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_IDLE);
}
return true;
}
else
{
return Super::Use (pickup);
}
}
// Time bomb ----------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
{
PARAM_ACTION_PROLOGUE;
self->AddZ(32, false);
self->RenderStyle = STYLE_Add;
self->Alpha = 1.;
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
P_CheckSplash(self, 128);
return 0;
}
class AArtiTimeBomb : public AInventory
{
DECLARE_CLASS (AArtiTimeBomb, AInventory)
public:
bool Use (bool pickup);
};
IMPLEMENT_CLASS (AArtiTimeBomb)
bool AArtiTimeBomb::Use (bool pickup)
{
AActor *mo = Spawn("ActivatedTimeBomb",
Owner->Vec3Angle(24., Owner->Angles.Yaw, - Owner->Floorclip), ALLOW_REPLACE);
mo->target = Owner;
return true;
}

View file

@ -1,96 +0,0 @@
/*
#include "templates.h"
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_impmsatk ("ImpMsAttack");
static FRandom pr_imp ("ImpExplode");
//----------------------------------------------------------------------------
//
// PROC A_ImpMsAttack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target || pr_impmsatk() > 64)
{
self->SetState (self->SeeState);
return 0;
}
A_SkullAttack(self, 12.);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_ImpExplode
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
{
PARAM_ACTION_PROLOGUE;
AActor *chunk;
self->flags &= ~MF_NOGRAVITY;
chunk = Spawn("HereticImpChunk1", self->Pos(), ALLOW_REPLACE);
chunk->Vel.X = pr_imp.Random2() / 64.;
chunk->Vel.Y = pr_imp.Random2() / 64.;
chunk->Vel.Z = 9;
chunk = Spawn("HereticImpChunk2", self->Pos(), ALLOW_REPLACE);
chunk->Vel.X = pr_imp.Random2() / 64.;
chunk->Vel.Y = pr_imp.Random2() / 64.;
chunk->Vel.Z = 9;
if (self->special1 == 666)
{ // Extreme death crash
self->SetState (self->FindState("XCrash"));
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_ImpDeath
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath)
{
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_SOLID;
self->flags2 |= MF2_FLOORCLIP;
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_ImpXDeath1
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ImpXDeath1)
{
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_SOLID;
self->flags |= MF_NOGRAVITY;
self->flags2 |= MF2_FLOORCLIP;
self->special1 = 666; // Flag the crash routine
return 0;
}

View file

@ -1,219 +0,0 @@
#include "actor.h"
#include "info.h"
#include "a_pickups.h"
#include "a_action.h"
#include "m_random.h"
#include "p_local.h"
#include "s_sound.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
#include "p_enemy.h"
#include "a_specialspot.h"
#include "g_level.h"
#include "a_sharedglobal.h"
#include "templates.h"
#include "r_data/r_translate.h"
#include "doomstat.h"
#include "d_player.h"
#include "a_morph.h"
#include "p_spec.h"
#include "serializer.h"
// Include all the other Heretic stuff here to reduce compile time
#include "a_chicken.cpp"
#include "a_dsparil.cpp"
#include "a_hereticartifacts.cpp"
#include "a_hereticimp.cpp"
#include "a_hereticweaps.cpp"
#include "a_ironlich.cpp"
#include "a_knight.cpp"
#include "a_wizard.cpp"
static FRandom pr_podpain ("PodPain");
static FRandom pr_makepod ("MakePod");
static FRandom pr_teleg ("TeleGlitter");
static FRandom pr_teleg2 ("TeleGlitter2");
static FRandom pr_volcano ("VolcanoSet");
static FRandom pr_blast ("VolcanoBlast");
static FRandom pr_volcimpact ("VolcBallImpact");
//----------------------------------------------------------------------------
//
// PROC A_PodPain
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (gootype, AActor) { gootype = PClass::FindActor("PodGoo"); }
int count;
int chance;
AActor *goo;
chance = pr_podpain ();
if (chance < 128)
{
return 0;
}
for (count = chance > 240 ? 2 : 1; count; count--)
{
goo = Spawn(gootype, self->PosPlusZ(48.), ALLOW_REPLACE);
goo->target = self;
goo->Vel.X = pr_podpain.Random2() / 128.;
goo->Vel.Y = pr_podpain.Random2() / 128.;
goo->Vel.Z = 0.5 + pr_podpain() / 128.;
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_RemovePod
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
if ( (mo = self->master) )
{
if (mo->special1 > 0)
{
mo->special1--;
}
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_MakePod
//
//----------------------------------------------------------------------------
#define MAX_GEN_PODS 16
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); }
AActor *mo;
if (self->special1 == MAX_GEN_PODS)
{ // Too many generated pods
return 0;
}
mo = Spawn(podtype, self->PosAtZ(ONFLOORZ), ALLOW_REPLACE);
if (!P_CheckPosition (mo, mo->Pos()))
{ // Didn't fit
mo->Destroy ();
return 0;
}
mo->SetState (mo->FindState("Grow"));
mo->Thrust(pr_makepod() * (360. / 256), 4.5);
S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE);
self->special1++; // Increment generated pod count
mo->master = self; // Link the generator to the pod
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_AccTeleGlitter
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
{
PARAM_ACTION_PROLOGUE;
if (++self->health > 35)
{
self->Vel.Z *= 1.5;
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_VolcanoSet
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
{
PARAM_ACTION_PROLOGUE;
self->tics = 105 + (pr_volcano() & 127);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_VolcanoBlast
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
{
PARAM_ACTION_PROLOGUE;
int i;
int count;
AActor *blast;
count = 1 + (pr_blast() % 3);
for (i = 0; i < count; i++)
{
blast = Spawn("VolcanoBlast", self->PosPlusZ(44.), ALLOW_REPLACE);
blast->target = self;
blast->Angles.Yaw = pr_blast() * (360 / 256.);
blast->VelFromAngle(1.);
blast->Vel.Z = 2.5 + pr_blast() / 64.;
S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
P_CheckMissileSpawn (blast, self->radius);
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_VolcBallImpact
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
{
PARAM_ACTION_PROLOGUE;
unsigned int i;
AActor *tiny;
if (self->Z() <= self->floorz)
{
self->flags |= MF_NOGRAVITY;
self->Gravity = 1;
self->AddZ(28);
//self->Vel.Z = 3;
}
P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE);
for (i = 0; i < 4; i++)
{
tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE);
tiny->target = self;
tiny->Angles.Yaw = 90.*i;
tiny->VelFromAngle(0.7);
tiny->Vel.Z = 1. + pr_volcimpact() / 128.;
P_CheckMissileSpawn (tiny, self->radius);
}
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,213 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
*/
static FRandom pr_foo ("WhirlwindDamage");
static FRandom pr_atk ("LichAttack");
static FRandom pr_seek ("WhirlwindSeek");
class AWhirlwind : public AActor
{
DECLARE_CLASS (AWhirlwind, AActor)
public:
int DoSpecialDamage (AActor *target, int damage, FName damagetype);
};
IMPLEMENT_CLASS(AWhirlwind)
int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype)
{
int randVal;
if (!(target->flags7 & MF7_DONTTHRUST))
{
target->Angles.Yaw += pr_foo.Random2() * (360 / 4096.);
target->Vel.X += pr_foo.Random2() / 64.;
target->Vel.Y += pr_foo.Random2() / 64.;
}
if ((level.time & 16) && !(target->flags2 & MF2_BOSS) && !(target->flags7 & MF7_DONTTHRUST))
{
randVal = pr_foo();
if (randVal > 160)
{
randVal = 160;
}
target->Vel.Z += randVal / 32.;
if (target->Vel.Z > 12)
{
target->Vel.Z = 12;
}
}
if (!(level.time & 7))
{
P_DamageMobj (target, NULL, this->target, 3, NAME_Melee);
}
return -1;
}
//----------------------------------------------------------------------------
//
// PROC A_LichAttack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
{
PARAM_ACTION_PROLOGUE;
int i;
AActor *fire;
AActor *baseFire;
AActor *mo;
AActor *target;
int randAttack;
static const int atkResolve1[] = { 50, 150 };
static const int atkResolve2[] = { 150, 200 };
// Ice ball (close 20% : far 60%)
// Fire column (close 40% : far 20%)
// Whirlwind (close 40% : far 20%)
// Distance threshold = 8 cells
target = self->target;
if (target == NULL)
{
return 0;
}
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = pr_atk.HitDice (6);
int newdam = P_DamageMobj (target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, target, self);
return 0;
}
int dist = self->Distance2D(target) > 8 * 64;
randAttack = pr_atk ();
if (randAttack < atkResolve1[dist])
{ // Ice ball
P_SpawnMissile (self, target, PClass::FindActor("HeadFX1"));
S_Sound (self, CHAN_BODY, "ironlich/attack2", 1, ATTN_NORM);
}
else if (randAttack < atkResolve2[dist])
{ // Fire column
baseFire = P_SpawnMissile (self, target, PClass::FindActor("HeadFX3"));
if (baseFire != NULL)
{
baseFire->SetState (baseFire->FindState("NoGrow"));
for (i = 0; i < 5; i++)
{
fire = Spawn("HeadFX3", baseFire->Pos(), ALLOW_REPLACE);
if (i == 0)
{
S_Sound (self, CHAN_BODY, "ironlich/attack1", 1, ATTN_NORM);
}
fire->target = baseFire->target;
fire->Angles.Yaw = baseFire->Angles.Yaw;
fire->Vel = baseFire->Vel;
fire->SetDamage(0);
fire->health = (i+1) * 2;
P_CheckMissileSpawn (fire, self->radius);
}
}
}
else
{ // Whirlwind
mo = P_SpawnMissile (self, target, RUNTIME_CLASS(AWhirlwind));
if (mo != NULL)
{
mo->AddZ(-32);
mo->tracer = target;
mo->health = 20*TICRATE; // Duration
S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
}
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_WhirlwindSeek
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
{
PARAM_ACTION_PROLOGUE;
self->health -= 3;
if (self->health < 0)
{
self->Vel.Zero();
self->SetState(self->FindState(NAME_Death));
self->flags &= ~MF_MISSILE;
return 0;
}
if ((self->threshold -= 3) < 0)
{
self->threshold = 58 + (pr_seek() & 31);
S_Sound(self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
}
if (self->tracer && self->tracer->flags&MF_SHADOW)
{
return 0;
}
P_SeekerMissile(self, 10, 30);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_LichIceImpact
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
{
PARAM_ACTION_PROLOGUE;
unsigned int i;
AActor *shard;
for (i = 0; i < 8; i++)
{
shard = Spawn("HeadFX2", self->Pos(), ALLOW_REPLACE);
shard->target = self->target;
shard->Angles.Yaw = i*45.;
shard->VelFromAngle();
shard->Vel.Z = -.6;
P_CheckMissileSpawn (shard, self->radius);
}
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_LichFireGrow
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
{
PARAM_ACTION_PROLOGUE;
self->health--;
self->AddZ(9.);
if (self->health == 0)
{
self->RestoreDamage();
self->SetState (self->FindState("NoGrow"));
}
return 0;
}

View file

@ -1,70 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "a_action.h"
#include "a_sharedglobal.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_dripblood ("DripBlood");
static FRandom pr_knightatk ("KnightAttack");
//----------------------------------------------------------------------------
//
// PROC A_DripBlood
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
double xo = pr_dripblood.Random2() / 32.;
double yo = pr_dripblood.Random2() / 32.;
mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE);
mo->Vel.X = pr_dripblood.Random2 () / 64.;
mo->Vel.Y = pr_dripblood.Random2() / 64.;
mo->Gravity = 1./8;
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_KnightAttack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
{
return 0;
}
if (self->CheckMeleeRange ())
{
int damage = pr_knightatk.HitDice (3);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
S_Sound (self, CHAN_BODY, "hknight/melee", 1, ATTN_NORM);
return 0;
}
// Throw axe
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->flags & MF_SHADOW || pr_knightatk () < 40)
{ // Red axe
P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("RedAxe"));
return 0;
}
// Green axe
P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("KnightAxe"));
return 0;
}

View file

@ -1,95 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "gstrings.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_wizatk3 ("WizAtk3");
//----------------------------------------------------------------------------
//
// PROC A_GhostOff
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GhostOff)
{
PARAM_ACTION_PROLOGUE;
self->RenderStyle = STYLE_Normal;
self->flags3 &= ~MF3_GHOST;
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_WizAtk1
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1)
{
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self);
CALL_ACTION(A_GhostOff, self);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_WizAtk2
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2)
{
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self);
self->Alpha = HR_SHADOW;
self->RenderStyle = STYLE_Translucent;
self->flags3 |= MF3_GHOST;
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_WizAtk3
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
CALL_ACTION(A_GhostOff, self);
if (!self->target)
{
return 0;
}
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange())
{
int damage = pr_wizatk3.HitDice (4);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
PClassActor *fx = PClass::FindActor("WizardFX1");
mo = P_SpawnMissile (self, self->target, fx);
if (mo != NULL)
{
P_SpawnMissileAngle(self, fx, mo->Angles.Yaw - 45. / 8, mo->Vel.Z);
P_SpawnMissileAngle(self, fx, mo->Angles.Yaw + 45. / 8, mo->Vel.Z);
}
return 0;
}

View file

@ -1,98 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "p_local.h"
#include "s_sound.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_batspawn ("BatSpawn");
static FRandom pr_batmove ("BatMove");
//===========================================================================
// Bat Spawner Variables
// special1 frequency counter
// special2
// args[0] frequency of spawn (1=fastest, 10=slowest)
// args[1] spread angle (0..255)
// args[2]
// args[3] duration of bats (in octics)
// args[4] turn amount per move (in degrees)
//
// Bat Variables
// special2 lifetime counter
// args[4] turn amount per move (in degrees)
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BatSpawnInit)
{
PARAM_ACTION_PROLOGUE;
self->special1 = 0; // Frequency count
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
int delta;
DAngle angle;
// Countdown until next spawn
if (self->special1-- > 0) return 0;
self->special1 = self->args[0]; // Reset frequency count
delta = self->args[1];
if (delta==0) delta=1;
angle = self->Angles.Yaw + (((pr_batspawn() % delta) - (delta >> 1)) * (360 / 256.));
mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0);
if (mo)
{
mo->args[0] = pr_batspawn()&63; // floatbob index
mo->args[4] = self->args[4]; // turn degrees
mo->special2 = self->args[3]<<3; // Set lifetime
mo->target = self;
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
{
PARAM_ACTION_PROLOGUE;
DAngle newangle;
if (self->special2 < 0)
{
self->SetState (self->FindState(NAME_Death));
}
self->special2 -= 2; // Called every 2 tics
if (pr_batmove()<128)
{
newangle = self->Angles.Yaw + self->args[4];
}
else
{
newangle = self->Angles.Yaw - self->args[4];
}
// Adjust velocity vector to new direction
self->VelFromAngle(newangle, self->Speed);
if (pr_batmove()<15)
{
S_Sound (self, CHAN_VOICE, "BatScream", 1, ATTN_IDLE);
}
// Handle Z movement
self->SetZ(self->target->Z() + 2 * BobSin(self->args[0]));
self->args[0] = (self->args[0]+3)&63;
return 0;
}

View file

@ -1,230 +0,0 @@
/*
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "s_sound.h"
#include "a_action.h"
#include "m_random.h"
#include "a_hexenglobal.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_boom ("BishopBoom");
static FRandom pr_atk ("BishopAttack");
static FRandom pr_decide ("BishopDecide");
static FRandom pr_doblur ("BishopDoBlur");
static FRandom pr_sblur ("BishopSpawnBlur");
static FRandom pr_pain ("BishopPainBlur");
//============================================================================
//
// A_BishopAttack
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target)
{
return 0;
}
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange())
{
int damage = pr_atk.HitDice (4);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
self->special1 = (pr_atk() & 3) + 5;
return 0;
}
//============================================================================
//
// A_BishopAttack2
//
// Spawns one of a string of bishop missiles
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
if (!self->target || !self->special1)
{
self->special1 = 0;
self->SetState (self->SeeState);
return 0;
}
mo = P_SpawnMissile (self, self->target, PClass::FindActor("BishopFX"));
if (mo != NULL)
{
mo->tracer = self->target;
}
self->special1--;
return 0;
}
//============================================================================
//
// A_BishopMissileWeave
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{
PARAM_ACTION_PROLOGUE;
A_Weave(self, 2, 2, 2., 1.);
return 0;
}
//============================================================================
//
// A_BishopDecide
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopDecide)
{
PARAM_ACTION_PROLOGUE;
if (pr_decide() < 220)
{
return 0;
}
else
{
self->SetState (self->FindState ("Blur"));
}
return 0;
}
//============================================================================
//
// A_BishopDoBlur
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
{
PARAM_ACTION_PROLOGUE;
self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
if (pr_doblur() < 120)
{
self->Thrust(self->Angles.Yaw + 90, 11);
}
else if (pr_doblur() > 125)
{
self->Thrust(self->Angles.Yaw - 90, 11);
}
else
{ // Thrust forward
self->Thrust(11);
}
S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);
return 0;
}
//============================================================================
//
// A_BishopSpawnBlur
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
if (!--self->special1)
{
self->Vel.X = self->Vel.Y = 0;
if (pr_sblur() > 96)
{
self->SetState (self->SeeState);
}
else
{
self->SetState (self->MissileState);
}
}
mo = Spawn ("BishopBlur", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->Angles.Yaw = self->Angles.Yaw;
}
return 0;
}
//============================================================================
//
// A_BishopChase
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
{
PARAM_ACTION_PROLOGUE;
double newz = self->Z() - BobSin(self->special2) / 2.;
self->special2 = (self->special2 + 4) & 63;
newz += BobSin(self->special2) / 2.;
self->SetZ(newz);
return 0;
}
//============================================================================
//
// A_BishopPuff
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
mo = Spawn ("BishopPuff", self->PosPlusZ(40.), ALLOW_REPLACE);
if (mo)
{
mo->Vel.Z = -.5;
}
return 0;
}
//============================================================================
//
// A_BishopPainBlur
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
if (pr_pain() < 64)
{
self->SetState (self->FindState ("Blur"));
return 0;
}
double xo = pr_pain.Random2() / 16.;
double yo = pr_pain.Random2() / 16.;
double zo = pr_pain.Random2() / 32.;
mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->Angles.Yaw = self->Angles.Yaw;
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show more