mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 06:41:41 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
# Conflicts: # src/CMakeLists.txt # src/p_setup.cpp # src/r_defs.h # src/version.h This only updates to a compileable state. The new portals are not yet functional in the hardware renderer because they require some refactoring in the data management first.
This commit is contained in:
commit
dda73b531c
260 changed files with 25409 additions and 9004 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -22,6 +22,9 @@
|
|||
/src/xlat/xlat_parser.c
|
||||
/src/xlat/xlat_parser.h
|
||||
/src/xlat/xlat_parser.out
|
||||
/src/zscript/zcc-parse.c
|
||||
/src/zscript/zcc-parse.h
|
||||
/src/zscript/zcc-parse.out
|
||||
/tools/*/debug
|
||||
/tools/*/release
|
||||
/tools/*/*.exe
|
||||
|
|
|
@ -735,6 +735,12 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CUR
|
|||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
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 ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/zscript/zcc-parse.lemon .
|
||||
COMMAND lemon zcc-parse.lemon
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/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
|
||||
DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re )
|
||||
|
@ -801,6 +807,7 @@ file( GLOB HEADER_FILES
|
|||
textures/*.h
|
||||
thingdef/*.h
|
||||
xlat/*.h
|
||||
zscript/*.h
|
||||
gl/*.h
|
||||
gl/api/*.h
|
||||
gl/data/*.h
|
||||
|
@ -901,6 +908,9 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
xlat/xlat_parser.y
|
||||
xlat_parser.c
|
||||
xlat_parser.h
|
||||
zscript/zcc-parse.lemon
|
||||
zcc-parse.c
|
||||
zcc-parse.h
|
||||
|
||||
# We could have the ASM macro add these files, but it wouldn't add all
|
||||
# platforms.
|
||||
|
@ -1035,6 +1045,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
p_xlat.cpp
|
||||
parsecontext.cpp
|
||||
po_man.cpp
|
||||
portal.cpp
|
||||
r_swrenderer.cpp
|
||||
r_utility.cpp
|
||||
r_3dfloors.cpp
|
||||
|
@ -1264,7 +1275,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
thingdef/thingdef_data.cpp
|
||||
thingdef/thingdef_exp.cpp
|
||||
thingdef/thingdef_expression.cpp
|
||||
thingdef/thingdef_function.cpp
|
||||
thingdef/thingdef_parse.cpp
|
||||
thingdef/thingdef_properties.cpp
|
||||
thingdef/thingdef_states.cpp
|
||||
|
@ -1299,6 +1309,14 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
r_data/renderstyle.cpp
|
||||
r_data/r_interpolate.cpp
|
||||
r_data/r_translate.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
|
||||
zzautozend.cpp
|
||||
)
|
||||
|
||||
|
@ -1325,6 +1343,7 @@ include_directories( .
|
|||
thingdef
|
||||
timidity
|
||||
xlat
|
||||
zscript
|
||||
../gdtoa
|
||||
../dumb/include
|
||||
${CMAKE_BINARY_DIR}/gdtoa
|
||||
|
@ -1459,4 +1478,5 @@ source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_sh
|
|||
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/.+")
|
||||
source_group("Source Files" FILES ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h sc_man_scanner.re)
|
||||
|
|
|
@ -46,24 +46,26 @@
|
|||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#pragma comment(linker, "/merge:.areg=.data /merge:.creg=.data /merge:.greg=.data /merge:.mreg=.data /merge:.yreg=.data")
|
||||
// The various reg sections are used to group pointers spread across multiple
|
||||
// source files into cohesive arrays in the final executable. We don't
|
||||
// actually care about these sections themselves and merge them all into
|
||||
// a single section during the final link. (.rdata is the standard section
|
||||
// for initialized read-only data.)
|
||||
|
||||
#pragma data_seg(".areg$a")
|
||||
void *ARegHead = 0;
|
||||
#pragma comment(linker, "/merge:.areg=.rdata /merge:.creg=.rdata /merge:.greg=.rdata")
|
||||
#pragma comment(linker, "/merge:.yreg=.rdata")
|
||||
|
||||
#pragma data_seg(".creg$a")
|
||||
void *CRegHead = 0;
|
||||
#pragma section(".areg$a",read)
|
||||
__declspec(allocate(".areg$a")) void *const ARegHead = 0;
|
||||
|
||||
#pragma data_seg(".greg$a")
|
||||
void *GRegHead = 0;
|
||||
#pragma section(".creg$a",read)
|
||||
__declspec(allocate(".creg$a")) void *const CRegHead = 0;
|
||||
|
||||
#pragma data_seg(".mreg$a")
|
||||
void *MRegHead = 0;
|
||||
#pragma section(".greg$a",read)
|
||||
__declspec(allocate(".greg$a")) void *const GRegHead = 0;
|
||||
|
||||
#pragma data_seg(".yreg$a")
|
||||
void *YRegHead = 0;
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma section(".yreg$a",read)
|
||||
__declspec(allocate(".yreg$a")) void *const YRegHead = 0;
|
||||
|
||||
// We want visual styles support under XP
|
||||
#if defined _M_IX86
|
||||
|
@ -88,11 +90,15 @@ void *YRegHead = 0;
|
|||
|
||||
#include "doomtype.h"
|
||||
|
||||
void *ARegHead __attribute__((section(SECTION_AREG))) = 0;
|
||||
void *CRegHead __attribute__((section(SECTION_CREG))) = 0;
|
||||
void *GRegHead __attribute__((section(SECTION_GREG))) = 0;
|
||||
void *MRegHead __attribute__((section(SECTION_MREG))) = 0;
|
||||
void *YRegHead __attribute__((section(SECTION_YREG))) = 0;
|
||||
// I don't know of an easy way to merge sections together with the GNU linker,
|
||||
// so GCC users will see all of these sections appear in the final executable.
|
||||
// (There are linker scripts, but that apparently involves extracting the
|
||||
// default script from ld and then modifying it.)
|
||||
|
||||
void *const ARegHead __attribute__((section(SECTION_AREG))) = 0;
|
||||
void *const CRegHead __attribute__((section(SECTION_CREG))) = 0;
|
||||
void *const GRegHead __attribute__((section(SECTION_GREG))) = 0;
|
||||
void *const YRegHead __attribute__((section(SECTION_YREG))) = 0;
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2)
|
|||
DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1)
|
||||
DEFINE_SPECIAL(StartConversation, 18, 1, 2, 2)
|
||||
DEFINE_SPECIAL(Thing_Stop, 19, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Floor_LowerByValue, 20, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowest, 21, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_LowerToNearest, 22, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_RaiseByValue, 23, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToHighest, 24, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_RaiseToNearest, 25, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_LowerByValue, 20, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowest, 21, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerToNearest, 22, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseByValue, 23, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_RaiseToHighest, 24, 2, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_RaiseToNearest, 25, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Stairs_BuildDown, 26, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Stairs_BuildUp, 27, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_RaiseAndCrush, 28, 3, 4, 4)
|
||||
|
@ -33,19 +33,19 @@ DEFINE_SPECIAL(Stairs_BuildDownSync, 31, 4, 4, 4)
|
|||
DEFINE_SPECIAL(Stairs_BuildUpSync, 32, 4, 4, 4)
|
||||
DEFINE_SPECIAL(ForceField, 33, 0, 0, 0) // [RH] Strife's forcefield special (148)
|
||||
DEFINE_SPECIAL(ClearForceField, 34, 1, 1, 1) // [RH] Remove Strife's forcefield from tagged sectors
|
||||
DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 5)
|
||||
DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 5) // [RH] Complement of Floor_Waggle
|
||||
DEFINE_SPECIAL(Teleport_ZombieChanger, 39, 2, 2, 2) // [RH] Needed for Strife
|
||||
DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_CrushAndRaise, 42, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerAndCrush, 43, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_CrushStop, 44, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Ceiling_CrushRaiseAndStay, 45, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_CrushStop, 46, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Ceiling_MoveToValue, 47, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_MoveToValue, 47, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Sector_Attach3dMidtex, 48, -1, -1, 3)
|
||||
DEFINE_SPECIAL(GlassBreak, 49, 0, 1, 1)
|
||||
DEFINE_SPECIAL(ExtraFloor_LightOnly, 50, -1, -1, 2)
|
||||
|
@ -64,10 +64,10 @@ DEFINE_SPECIAL(Plat_DownWaitUpStay, 62, 3, 3, 3)
|
|||
DEFINE_SPECIAL(Plat_DownByValue, 63, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Plat_UpWaitDownStay, 64, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Plat_UpByValue, 65, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerInstant, 66, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseInstant, 67, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_MoveToValueTimes8, 68, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_MoveToValueTimes8, 69, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerInstant, 66, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_RaiseInstant, 67, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_MoveToValueTimes8, 68, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_MoveToValueTimes8, 69, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Teleport, 70, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Teleport_NoFog, 71, 1, 4, 4)
|
||||
DEFINE_SPECIAL(ThrustThing, 72, 2, 4, 4)
|
||||
|
@ -103,6 +103,8 @@ DEFINE_SPECIAL(Scroll_Texture_Right, 101, -1, -1, 2)
|
|||
DEFINE_SPECIAL(Scroll_Texture_Up, 102, -1, -1, 2)
|
||||
DEFINE_SPECIAL(Scroll_Texture_Down, 103, -1, -1, 2)
|
||||
DEFINE_SPECIAL(Ceiling_CrushAndRaiseSilentDist, 104, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Door_WaitRaise, 105, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Door_WaitClose, 106, 4, 5, 5)
|
||||
|
||||
DEFINE_SPECIAL(Light_ForceLightning, 109, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Light_RaiseByValue, 110, 2, 2, 2)
|
||||
|
@ -136,6 +138,9 @@ DEFINE_SPECIAL(Thing_SpawnFacing, 139, 2, 4, 4)
|
|||
DEFINE_SPECIAL(Sector_ChangeSound, 140, 2, 2, 2)
|
||||
|
||||
DEFINE_SPECIAL(Teleport_NoStop, 154, 2, 3, 3)
|
||||
// portal specials
|
||||
DEFINE_SPECIAL(Line_SetVisualPortal, 155, -1, -1, 3)
|
||||
DEFINE_SPECIAL(Line_SetPortal, 156, -1, -1, 3)
|
||||
// GZDoom/Vavoom specials
|
||||
// Although ZDoom doesn't support them it's better to have them defined so that
|
||||
// WADs using them somewhere can at least be started without aborting due
|
||||
|
@ -171,14 +176,14 @@ DEFINE_SPECIAL(Sector_SetCeilingScale, 188, 5, 5, 5)
|
|||
DEFINE_SPECIAL(Sector_SetFloorScale, 189, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Static_Init, 190, -1, -1, 4)
|
||||
DEFINE_SPECIAL(SetPlayerProperty, 191, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseInstant, 194, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseInstant, 194, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_CrushRaiseAndStayA, 195, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_CrushAndRaiseA, 196, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_CrushAndRaiseSilentA, 197, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByValueTimes8, 198, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerByValueTimes8, 199, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByValueTimes8, 198, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerByValueTimes8, 199, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Generic_Floor, 200, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Generic_Ceiling, 201, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Generic_Door, 202, 5, 5, 5)
|
||||
|
@ -217,9 +222,9 @@ DEFINE_SPECIAL(Light_MaxNeighbor, 234, 1, 1, 1)
|
|||
DEFINE_SPECIAL(Floor_TransferTrigger, 235, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Floor_TransferNumeric, 236, 1, 1, 1)
|
||||
DEFINE_SPECIAL(ChangeCamera, 237, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_RaiseByValueTxTy, 239, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowestTxTy, 241, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Floor_LowerToHighest, 242, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Exit_Normal, 243, 1, 1, 1)
|
||||
|
@ -231,9 +236,27 @@ DEFINE_SPECIAL(HealThing, 248, 1, 2, 2)
|
|||
DEFINE_SPECIAL(Door_CloseWaitOpen, 249, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_Donut, 250, 3, 3, 3)
|
||||
DEFINE_SPECIAL(FloorAndCeiling_LowerRaise, 251, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 2, 2)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_CrushRaiseAndStaySilA, 255, 4, 5, 5)
|
||||
|
||||
DEFINE_SPECIAL(Floor_LowerToHighestEE, 256, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowest, 257, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowestCeiling, 258, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToCeiling, 259, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_ToCeilingInstant, 260, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerByTexture, 261, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToHighest, 262, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_ToHighestInstant, 263, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToNearest, 264, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToLowest, 265, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToHighestFloor, 266, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_ToFloorInstant, 267, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByTexture, 268, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerByTexture, 269, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Stairs_BuildDownDoom, 270, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Stairs_BuildUpDoomSync, 271, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Stairs_BuildDownDoomSync, 272, 4, 4, 4)
|
||||
|
||||
#undef DEFINE_SPECIAL
|
||||
|
|
134
src/actor.h
134
src/actor.h
|
@ -42,6 +42,8 @@
|
|||
#include "tflags.h"
|
||||
|
||||
struct subsector_t;
|
||||
class PClassAmmo;
|
||||
|
||||
//
|
||||
// NOTES: AActor
|
||||
//
|
||||
|
@ -278,7 +280,7 @@ enum ActorFlag4
|
|||
enum ActorFlag5
|
||||
{
|
||||
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
|
||||
/* = 0x00000002, reserved for use by scripting branch */
|
||||
MF5_INSTATECALL = 0x00000002, // This actor is being run through CallStateChain
|
||||
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
||||
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
|
||||
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
|
||||
|
@ -560,67 +562,54 @@ inline AActor *GetDefaultByType (const PClass *type)
|
|||
template<class T>
|
||||
inline T *GetDefault ()
|
||||
{
|
||||
return (T *)(RUNTIME_CLASS(T)->Defaults);
|
||||
return (T *)(RUNTIME_CLASS_CASTLESS(T)->Defaults);
|
||||
}
|
||||
|
||||
struct line_t;
|
||||
struct secplane_t;
|
||||
struct FStrifeDialogueNode;
|
||||
|
||||
enum
|
||||
{
|
||||
AMETA_BASE = 0x12000,
|
||||
|
||||
AMETA_Obituary, // string (player was killed by this actor)
|
||||
AMETA_HitObituary, // string (player was killed by this actor in melee)
|
||||
AMETA_DeathHeight, // fixed (height on normal death)
|
||||
AMETA_BurnHeight, // fixed (height on burning death)
|
||||
AMETA_StrifeName, // string (for named Strife objects)
|
||||
AMETA_BloodColor, // colorized blood
|
||||
AMETA_GibHealth, // negative health below which this monster dies an extreme death
|
||||
AMETA_WoundHealth, // health needed to enter wound state
|
||||
AMETA_FastSpeed, // Speed in fast mode
|
||||
AMETA_RDFactor, // Radius damage factor
|
||||
AMETA_CameraHeight, // Height of camera when used as such
|
||||
AMETA_HowlSound, // Sound being played when electrocuted or poisoned
|
||||
AMETA_BloodType, // Blood replacement type
|
||||
AMETA_BloodType2, // Bloodsplatter replacement type
|
||||
AMETA_BloodType3, // AxeBlood replacement type
|
||||
};
|
||||
|
||||
struct fixedvec3
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
|
||||
operator FVector3()
|
||||
{
|
||||
return FVector3(FIXED2FLOAT(x), FIXED2FLOAT(y), FIXED2FLOAT(z));
|
||||
}
|
||||
|
||||
operator TVector3<double>()
|
||||
{
|
||||
return TVector3<double>(FIXED2DBL(x), FIXED2DBL(y), FIXED2DBL(z));
|
||||
}
|
||||
};
|
||||
|
||||
struct fixedvec2
|
||||
{
|
||||
fixed_t x, y;
|
||||
};
|
||||
|
||||
struct FDropItem
|
||||
{
|
||||
FName Name;
|
||||
int probability;
|
||||
int amount;
|
||||
FDropItem * Next;
|
||||
};
|
||||
|
||||
class FDropItemPtrArray : public TArray<FDropItem *>
|
||||
{
|
||||
public:
|
||||
~FDropItemPtrArray()
|
||||
operator FVector2()
|
||||
{
|
||||
Clear();
|
||||
return FVector2(FIXED2FLOAT(x), FIXED2FLOAT(y));
|
||||
}
|
||||
|
||||
void Clear();
|
||||
operator TVector2<double>()
|
||||
{
|
||||
return TVector2<double>(FIXED2DBL(x), FIXED2DBL(y));
|
||||
}
|
||||
};
|
||||
|
||||
extern FDropItemPtrArray DropItemList;
|
||||
class DDropItem : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DDropItem, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DDropItem *Next;
|
||||
FName Name;
|
||||
int Probability;
|
||||
int Amount;
|
||||
};
|
||||
|
||||
void FreeDropItemChain(FDropItem *chain);
|
||||
int StoreDropItemChain(FDropItem *chain);
|
||||
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here...
|
||||
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h
|
||||
|
||||
|
@ -628,7 +617,7 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // sam
|
|||
// Map Object definition.
|
||||
class AActor : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (AActor, DThinker)
|
||||
DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
AActor () throw();
|
||||
|
@ -639,14 +628,14 @@ public:
|
|||
|
||||
void Serialize (FArchive &arc);
|
||||
|
||||
static AActor *StaticSpawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false);
|
||||
static AActor *StaticSpawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false);
|
||||
|
||||
inline AActor *GetDefault () const
|
||||
{
|
||||
return (AActor *)(RUNTIME_TYPE(this)->Defaults);
|
||||
return (AActor *)(this->GetClass()->Defaults);
|
||||
}
|
||||
|
||||
FDropItem *GetDropItems();
|
||||
DDropItem *GetDropItems() const;
|
||||
|
||||
// Return true if the monster should use a missile attack, false for melee
|
||||
bool SuggestMissileAttack (fixed_t dist);
|
||||
|
@ -727,7 +716,7 @@ public:
|
|||
// Take the amount value of an item from the inventory list.
|
||||
// If nothing is left, the item may be destroyed.
|
||||
// Returns true if the initial item count is positive.
|
||||
virtual bool TakeInventory (const PClass *itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
|
||||
virtual bool TakeInventory (PClassActor *itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
|
||||
|
||||
// Uses an item and removes it from the inventory.
|
||||
virtual bool UseInventory (AInventory *item);
|
||||
|
@ -742,21 +731,21 @@ public:
|
|||
bool CheckLocalView (int playernum) const;
|
||||
|
||||
// Finds the first item of a particular type.
|
||||
AInventory *FindInventory (const PClass *type, bool subclass = false);
|
||||
AInventory *FindInventory (PClassActor *type, bool subclass=false);
|
||||
AInventory *FindInventory (FName type);
|
||||
template<class T> T *FindInventory ()
|
||||
{
|
||||
return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
|
||||
return static_cast<T *> (FindInventory (RUNTIME_TEMPLATE_CLASS(T)));
|
||||
}
|
||||
|
||||
// Adds one item of a particular type. Returns NULL if it could not be added.
|
||||
AInventory *GiveInventoryType (const PClass *type);
|
||||
AInventory *GiveInventoryType (PClassActor *type);
|
||||
|
||||
// Returns the first item held with IF_INVBAR set.
|
||||
AInventory *FirstInv ();
|
||||
|
||||
// Tries to give the actor some ammo.
|
||||
bool GiveAmmo (const PClass *type, int amount);
|
||||
bool GiveAmmo (PClassAmmo *type, int amount);
|
||||
|
||||
// Destroys all the inventory the actor is holding.
|
||||
void DestroyAllInventory ();
|
||||
|
@ -810,8 +799,9 @@ public:
|
|||
void Crash();
|
||||
|
||||
// Return starting health adjusted by skill level
|
||||
int SpawnHealth();
|
||||
int GibHealth();
|
||||
int SpawnHealth() const;
|
||||
int GetGibHealth() const;
|
||||
fixed_t GetCameraHeight() const;
|
||||
|
||||
inline bool isMissile(bool precise=true)
|
||||
{
|
||||
|
@ -826,7 +816,7 @@ public:
|
|||
|
||||
PalEntry GetBloodColor() const
|
||||
{
|
||||
return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
|
||||
return GetClass()->BloodColor;
|
||||
}
|
||||
|
||||
// These also set CF_INTERPVIEW for players.
|
||||
|
@ -834,22 +824,25 @@ public:
|
|||
void SetAngle(angle_t ang, bool interpolate);
|
||||
void SetRoll(angle_t roll, bool interpolate);
|
||||
|
||||
const PClass *GetBloodType(int type = 0) const
|
||||
PClassActor *GetBloodType(int type = 0) const
|
||||
{
|
||||
const PClass *bloodcls;
|
||||
PClassActor *bloodcls;
|
||||
if (type == 0)
|
||||
{
|
||||
bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType);
|
||||
}
|
||||
else if (type == 1)
|
||||
{
|
||||
bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter));
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType2);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood));
|
||||
bloodcls = PClass::FindActor(GetClass()->BloodType3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
if (bloodcls != NULL)
|
||||
{
|
||||
|
@ -1020,7 +1013,7 @@ public:
|
|||
fixed_t velx, vely, velz; // velocity
|
||||
SDWORD tics; // state tic counter
|
||||
FState *state;
|
||||
SDWORD Damage; // For missiles and monster railgun
|
||||
VMFunction *Damage; // For missiles and monster railgun
|
||||
int projectileKickback;
|
||||
ActorFlags flags;
|
||||
ActorFlags2 flags2; // Heretic flags
|
||||
|
@ -1144,8 +1137,8 @@ public:
|
|||
|
||||
FNameNoInit PainType;
|
||||
FNameNoInit DeathType;
|
||||
const PClass *TeleFogSourceType;
|
||||
const PClass *TeleFogDestType;
|
||||
PClassActor *TeleFogSourceType;
|
||||
PClassActor *TeleFogDestType;
|
||||
int RipperLevel;
|
||||
int RipLevelMin;
|
||||
int RipLevelMax;
|
||||
|
@ -1200,18 +1193,18 @@ public:
|
|||
|
||||
FState *FindState (FName label) const
|
||||
{
|
||||
return GetClass()->ActorInfo->FindState(1, &label);
|
||||
return GetClass()->FindState(1, &label);
|
||||
}
|
||||
|
||||
FState *FindState (FName label, FName sublabel, bool exact = false) const
|
||||
{
|
||||
FName names[] = { label, sublabel };
|
||||
return GetClass()->ActorInfo->FindState(2, names, exact);
|
||||
return GetClass()->FindState(2, names, exact);
|
||||
}
|
||||
|
||||
FState *FindState(int numnames, FName *names, bool exact = false) const
|
||||
{
|
||||
return GetClass()->ActorInfo->FindState(numnames, names, exact);
|
||||
return GetClass()->FindState(numnames, names, exact);
|
||||
}
|
||||
|
||||
bool HasSpecialDeathStates () const;
|
||||
|
@ -1364,7 +1357,7 @@ public:
|
|||
do
|
||||
{
|
||||
actor = FActorIterator::Next ();
|
||||
} while (actor && !actor->IsKindOf (RUNTIME_CLASS(T)));
|
||||
} while (actor && !actor->IsKindOf (RUNTIME_TEMPLATE_CLASS(T)));
|
||||
return static_cast<T *>(actor);
|
||||
}
|
||||
};
|
||||
|
@ -1391,12 +1384,11 @@ public:
|
|||
bool P_IsTIDUsed(int tid);
|
||||
int P_FindUniqueTID(int start_tid, int limit);
|
||||
|
||||
inline AActor *Spawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
||||
inline AActor *Spawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
||||
{
|
||||
return AActor::StaticSpawn (type, x, y, z, allowreplacement);
|
||||
}
|
||||
|
||||
inline AActor *Spawn (const PClass *type, const fixedvec3 &pos, replace_t allowreplacement)
|
||||
inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowreplacement)
|
||||
{
|
||||
return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement);
|
||||
}
|
||||
|
@ -1418,13 +1410,13 @@ inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowrepl
|
|||
template<class T>
|
||||
inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
||||
{
|
||||
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), x, y, z, allowreplacement));
|
||||
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), x, y, z, allowreplacement));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement)
|
||||
{
|
||||
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), pos.x, pos.y, pos.z, allowreplacement));
|
||||
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), pos.x, pos.y, pos.z, allowreplacement));
|
||||
}
|
||||
|
||||
inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
|
||||
|
|
|
@ -66,13 +66,8 @@ enum AAPTR
|
|||
|
||||
AActor *COPY_AAPTR(AActor *origin, int selector);
|
||||
|
||||
// Use COPY_AAPTR_NOT_NULL to return from a function if the pointer is NULL
|
||||
#define COPY_AAPTR_NOT_NULL(source, destination, selector) { destination = COPY_AAPTR(source, selector); if (!destination) return; }
|
||||
|
||||
|
||||
|
||||
enum PTROP
|
||||
{
|
||||
{
|
||||
PTROP_UNSAFETARGET = 1,
|
||||
PTROP_UNSAFEMASTER = 2,
|
||||
PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER
|
||||
|
|
|
@ -2307,8 +2307,9 @@ bool AM_isExitBoundary (line_t& line)
|
|||
|
||||
bool AM_isTriggerSpecial (int special, int *)
|
||||
{
|
||||
return LineSpecialsInfo[special] != NULL
|
||||
&& LineSpecialsInfo[special]->max_args >= 0
|
||||
FLineSpecial *spec = P_GetLineSpecialInfo(special);
|
||||
return spec != NULL
|
||||
&& spec->max_args >= 0
|
||||
&& special != Door_Open
|
||||
&& special != Door_Close
|
||||
&& special != Door_CloseWaitOpen
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#define AUTOSEGS_H
|
||||
|
||||
#define REGMARKER(x) (x)
|
||||
typedef void *REGINFO;
|
||||
typedef void * const REGINFO;
|
||||
typedef void * NCREGINFO;
|
||||
|
||||
// List of Action functons
|
||||
extern REGINFO ARegHead;
|
||||
|
@ -50,10 +51,6 @@ extern REGINFO CRegTail;
|
|||
extern REGINFO GRegHead;
|
||||
extern REGINFO GRegTail;
|
||||
|
||||
// List of variables
|
||||
extern REGINFO MRegHead;
|
||||
extern REGINFO MRegTail;
|
||||
|
||||
// List of MAPINFO map options
|
||||
extern REGINFO YRegHead;
|
||||
extern REGINFO YRegTail;
|
||||
|
@ -76,7 +73,7 @@ class FAutoSegIterator
|
|||
}
|
||||
Probe = Head;
|
||||
}
|
||||
REGINFO operator*() const
|
||||
NCREGINFO operator*() const
|
||||
{
|
||||
return *Probe;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ void InitBotStuff()
|
|||
{
|
||||
w->MoveCombatDist = botinits[i].movecombatdist;
|
||||
w->WeaponFlags |= botinits[i].weaponflags;
|
||||
w->ProjectileType = PClass::FindClass(botinits[i].projectile);
|
||||
w->ProjectileType = PClass::FindActor(botinits[i].projectile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ void DBot::WhatToGet (AActor *item)
|
|||
// FIXME
|
||||
AWeapon *heldWeapon;
|
||||
|
||||
heldWeapon = static_cast<AWeapon *> (player->mo->FindInventory (item->GetClass()));
|
||||
heldWeapon = dyn_cast<AWeapon>(player->mo->FindInventory(item->GetClass()));
|
||||
if (heldWeapon != NULL)
|
||||
{
|
||||
if (!weapgiveammo)
|
||||
|
@ -343,7 +343,7 @@ void DBot::WhatToGet (AActor *item)
|
|||
else if (item->IsKindOf (RUNTIME_CLASS(AAmmo)))
|
||||
{
|
||||
AAmmo *ammo = static_cast<AAmmo *> (item);
|
||||
const PClass *parent = ammo->GetParentAmmo ();
|
||||
PClassActor *parent = ammo->GetParentAmmo ();
|
||||
AInventory *holdingammo = player->mo->FindInventory (parent);
|
||||
|
||||
if (holdingammo != NULL && holdingammo->Amount >= holdingammo->MaxAmount)
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
|
||||
const char *GetBind(unsigned int index) const
|
||||
{
|
||||
if (index < NUM_KEYS) return Binds[index];
|
||||
if (index < NUM_KEYS) return Binds[index].GetChars();
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
** It might be a good idea to move these into files that they are more
|
||||
** closely related to, but right now, I am too lazy to do that.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
@ -605,7 +603,7 @@ CCMD (special)
|
|||
}
|
||||
}
|
||||
Net_WriteByte(DEM_RUNSPECIAL);
|
||||
Net_WriteByte(specnum);
|
||||
Net_WriteWord(specnum);
|
||||
Net_WriteByte(argc - 2);
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
|
@ -929,8 +927,8 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha
|
|||
|
||||
if (FilterName != NULL)
|
||||
{
|
||||
FilterClass = PClass::FindClass(FilterName);
|
||||
if (FilterClass == NULL || FilterClass->ActorInfo == NULL)
|
||||
FilterClass = PClass::FindActor(FilterName);
|
||||
if (FilterClass == NULL)
|
||||
{
|
||||
Printf("%s is not an actor class.\n", FilterName);
|
||||
return;
|
||||
|
@ -1094,6 +1092,34 @@ CCMD(currentpos)
|
|||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CCMD(vmengine)
|
||||
{
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
if (stricmp(argv[1], "default") == 0)
|
||||
{
|
||||
VMSelectEngine(VMEngine_Default);
|
||||
return;
|
||||
}
|
||||
else if (stricmp(argv[1], "checked") == 0)
|
||||
{
|
||||
VMSelectEngine(VMEngine_Checked);
|
||||
return;
|
||||
}
|
||||
else if (stricmp(argv[1], "unchecked") == 0)
|
||||
{
|
||||
VMSelectEngine(VMEngine_Unchecked);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Printf("Usage: vmengine <default|checked|unchecked>\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Print secret info (submitted by Karl Murks)
|
||||
|
|
|
@ -1203,11 +1203,11 @@ static int DumpHash (FConsoleCommand **table, bool aliases, const char *pattern=
|
|||
|
||||
void FConsoleAlias::PrintAlias ()
|
||||
{
|
||||
if (m_Command[0])
|
||||
if (m_Command[0].IsNotEmpty())
|
||||
{
|
||||
Printf (TEXTCOLOR_YELLOW "%s : %s\n", m_Name, m_Command[0].GetChars());
|
||||
}
|
||||
if (m_Command[1])
|
||||
if (m_Command[1].IsNotEmpty())
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE "%s : %s\n", m_Name, m_Command[1].GetChars());
|
||||
}
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
#include "decallib.h"
|
||||
#include "v_palette.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "thingdef/thingdef_exp.h"
|
||||
#include "vectors.h"
|
||||
#include "dobject.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
@ -72,6 +70,7 @@
|
|||
#include "doomerrors.h"
|
||||
#include "p_effect.h"
|
||||
#include "farchive.h"
|
||||
#include "vmbuilder.h"
|
||||
|
||||
// [SO] Just the way Randy said to do it :)
|
||||
// [RH] Made this CVAR_SERVERINFO
|
||||
|
@ -82,7 +81,7 @@ static void UnloadDehSupp ();
|
|||
|
||||
|
||||
// This is a list of all the action functions used by each of Doom's states.
|
||||
static TArray<PSymbol *> Actions;
|
||||
static TArray<PFunction *> Actions;
|
||||
|
||||
// These are the original heights of every Doom 2 thing. They are used if a patch
|
||||
// specifies that a thing should be hanging from the ceiling but doesn't specify
|
||||
|
@ -110,7 +109,7 @@ struct StateMapper
|
|||
{
|
||||
FState *State;
|
||||
int StateSpan;
|
||||
const PClass *Owner;
|
||||
PClassActor *Owner;
|
||||
bool OwnerIsPickup;
|
||||
};
|
||||
|
||||
|
@ -121,7 +120,7 @@ static TArray<StateMapper> StateMap;
|
|||
static TArray<FSoundID> SoundMap;
|
||||
|
||||
// Names of different actor types, in original Doom 2 order
|
||||
static TArray<const PClass *> InfoNames;
|
||||
static TArray<PClassActor *> InfoNames;
|
||||
|
||||
// bit flags for PatchThing (a .bex extension):
|
||||
struct BitName
|
||||
|
@ -142,8 +141,8 @@ struct StyleName
|
|||
|
||||
static TArray<StyleName> StyleNames;
|
||||
|
||||
static TArray<const PClass *> AmmoNames;
|
||||
static TArray<const PClass *> WeaponNames;
|
||||
static TArray<PClassAmmo *> AmmoNames;
|
||||
static TArray<PClassActor *> WeaponNames;
|
||||
|
||||
// DeHackEd trickery to support MBF-style parameters
|
||||
// List of states that are hacked to use a codepointer
|
||||
|
@ -156,7 +155,7 @@ static TArray<MBFParamState> MBFParamStates;
|
|||
// Data on how to correctly modify the codepointers
|
||||
struct CodePointerAlias
|
||||
{
|
||||
char name[20];
|
||||
FName name;
|
||||
char alias[20];
|
||||
BYTE params;
|
||||
};
|
||||
|
@ -164,7 +163,7 @@ static TArray<CodePointerAlias> MBFCodePointers;
|
|||
|
||||
struct AmmoPerAttack
|
||||
{
|
||||
actionf_p func;
|
||||
VMNativeFunction **func;
|
||||
int ammocount;
|
||||
};
|
||||
|
||||
|
@ -174,7 +173,7 @@ DECLARE_ACTION(A_FireShotgun)
|
|||
DECLARE_ACTION(A_FireShotgun2)
|
||||
DECLARE_ACTION(A_FireCGun)
|
||||
DECLARE_ACTION(A_FireMissile)
|
||||
DECLARE_ACTION_PARAMS(A_Saw)
|
||||
DECLARE_ACTION(A_Saw)
|
||||
DECLARE_ACTION(A_FirePlasma)
|
||||
DECLARE_ACTION(A_FireBFG)
|
||||
DECLARE_ACTION(A_FireOldBFG)
|
||||
|
@ -182,17 +181,17 @@ DECLARE_ACTION(A_FireRailgun)
|
|||
|
||||
// Default ammo use of the various weapon attacks
|
||||
static AmmoPerAttack AmmoPerAttacks[] = {
|
||||
{ AF_A_Punch, 0},
|
||||
{ AF_A_FirePistol, 1},
|
||||
{ AF_A_FireShotgun, 1},
|
||||
{ AF_A_FireShotgun2, 2},
|
||||
{ AF_A_FireCGun, 1},
|
||||
{ AF_A_FireMissile, 1},
|
||||
{ AFP_A_Saw, 0},
|
||||
{ AF_A_FirePlasma, 1},
|
||||
{ AF_A_FireBFG, -1}, // uses deh.BFGCells
|
||||
{ AF_A_FireOldBFG, 1},
|
||||
{ AF_A_FireRailgun, 1},
|
||||
{ &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}
|
||||
};
|
||||
|
||||
|
@ -232,7 +231,7 @@ IMPLEMENT_POINTY_CLASS (ADehackedPickup)
|
|||
DECLARE_POINTER (RealPickup)
|
||||
END_POINTERS
|
||||
|
||||
TArray<PClass *> TouchedActors;
|
||||
TArray<PClassActor *> TouchedActors;
|
||||
|
||||
char *UnchangedSpriteNames;
|
||||
int NumUnchangedSprites;
|
||||
|
@ -354,11 +353,14 @@ static bool ReadChars (char **stuff, int size);
|
|||
static char *igets (void);
|
||||
static int GetLine (void);
|
||||
|
||||
static void PushTouchedActor(PClass *cls)
|
||||
static void PushTouchedActor(PClassActor *cls)
|
||||
{
|
||||
for(unsigned i = 0; i < TouchedActors.Size(); i++)
|
||||
{
|
||||
if (TouchedActors[i] == cls) return;
|
||||
if (TouchedActors[i] == cls)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
TouchedActors.Push(cls);
|
||||
}
|
||||
|
@ -426,7 +428,7 @@ static FState *FindState (int statenum)
|
|||
{
|
||||
if (StateMap[i].OwnerIsPickup)
|
||||
{
|
||||
PushTouchedActor(const_cast<PClass *>(StateMap[i].Owner));
|
||||
PushTouchedActor(StateMap[i].Owner);
|
||||
}
|
||||
return StateMap[i].State + statenum - stateacc;
|
||||
}
|
||||
|
@ -632,28 +634,149 @@ static int GetLine (void)
|
|||
}
|
||||
}
|
||||
|
||||
// This enum must be in sync with the Aliases array in DEHSUPP.
|
||||
enum MBFCodePointers
|
||||
// misc1 = vrange (arg +3), misc2 = hrange (arg+4)
|
||||
static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_Mushroom
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // spawntype
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // numspawns
|
||||
buildit.Emit(OP_PARAMI, 1); // flag
|
||||
// vrange
|
||||
if (value1 == 0)
|
||||
{
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value1)));
|
||||
}
|
||||
// hrange
|
||||
if (value2 == 0)
|
||||
{
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value2)));
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
// misc1 = type (arg +0), misc2 = Z-pos (arg +2)
|
||||
static int CreateSpawnFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_SpawnItem
|
||||
if (InfoNames[value1-1] == NULL)
|
||||
{
|
||||
I_Error("No class found for dehackednum %d!\n", value1+1);
|
||||
return 0;
|
||||
}
|
||||
int typereg = buildit.GetConstantAddress(InfoNames[value1-1], ATAG_OBJECT);
|
||||
int heightreg = buildit.GetConstantFloat(value2);
|
||||
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, typereg); // itemtype
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // distance
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, heightreg); // height
|
||||
// The rest of the parameters to A_SpawnItem can just keep their defaults
|
||||
return 3;
|
||||
}
|
||||
|
||||
// misc1 = angle (in degrees) (arg +0 but factor in current actor angle too)
|
||||
static int CreateTurnFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_Turn
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle
|
||||
return 1;
|
||||
}
|
||||
|
||||
// misc1 = angle (in degrees) (arg +0)
|
||||
static int CreateFaceFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_FaceTarget
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle
|
||||
return 1;
|
||||
}
|
||||
|
||||
// misc1 = damage, misc 2 = sound
|
||||
static int CreateScratchFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_CustomMeleeAttack
|
||||
buildit.EmitParamInt(value1); // damage
|
||||
if (value2)
|
||||
{
|
||||
buildit.EmitParamInt(SoundMap[value2-1]); // hit sound
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// misc1 = sound, misc2 = attenuation none (true) or normal (false)
|
||||
static int CreatePlaySoundFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_PlaySound
|
||||
int float1 = buildit.GetConstantFloat(1);
|
||||
int attenreg = buildit.GetConstantFloat(value2 ? ATTN_NONE : ATTN_NORM);
|
||||
|
||||
buildit.EmitParamInt(SoundMap[value1-1]); // soundid
|
||||
buildit.Emit(OP_PARAMI, CHAN_BODY); // channel
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, float1); // volume
|
||||
buildit.Emit(OP_PARAMI, false); // looping
|
||||
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, attenreg); // attenuation
|
||||
return 5;
|
||||
}
|
||||
|
||||
// misc1 = state, misc2 = probability
|
||||
static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_Jump
|
||||
int statereg = buildit.GetConstantAddress(FindState(value1), ATAG_STATE);
|
||||
|
||||
buildit.EmitParamInt(value2); // maxchance
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, statereg); // jumpto
|
||||
return 2;
|
||||
}
|
||||
|
||||
// misc1 = Boom linedef type, misc2 = sector tag
|
||||
static int CreateLineEffectFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_LineEffect
|
||||
// This is the second MBF codepointer that couldn't be translated easily.
|
||||
// Calling P_TranslateLineDef() here was a simple matter, as was adding an
|
||||
// extra parameter to A_CallSpecial so as to replicate the LINEDONE stuff,
|
||||
// but unfortunately DEHACKED lumps are processed before the map translation
|
||||
// arrays are initialized so this didn't work.
|
||||
buildit.EmitParamInt(value1); // special
|
||||
buildit.EmitParamInt(value2); // tag
|
||||
return 2;
|
||||
}
|
||||
|
||||
// No misc, but it's basically A_Explode with an added effect
|
||||
static int CreateNailBombFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_Explode
|
||||
// This one does not actually have MBF-style parameters. But since
|
||||
// we're aliasing it to an extension of A_Explode...
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // damage
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // distance
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // flags
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // alert
|
||||
buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // fulldamagedistance
|
||||
buildit.Emit(OP_PARAMI, 30); // nails
|
||||
buildit.Emit(OP_PARAMI, 10); // naildamage
|
||||
return 7;
|
||||
}
|
||||
|
||||
// This array must be in sync with the Aliases array in DEHSUPP.
|
||||
static int (*MBFCodePointerFactories[])(VMFunctionBuilder&, int, int) =
|
||||
{
|
||||
// Die and Detonate are not in this list because these codepointers have
|
||||
// no dehacked arguments and therefore do not need special handling.
|
||||
// NailBomb has no argument but is implemented as new parameters for A_Explode.
|
||||
MBF_Mushroom, // misc1 = vrange (arg +3), misc2 = hrange (arg+4)
|
||||
MBF_Spawn, // misc1 = type (arg +0), misc2 = Z-pos (arg +2)
|
||||
MBF_Turn, // misc1 = angle (in degrees) (arg +0 but factor in current actor angle too)
|
||||
MBF_Face, // misc1 = angle (in degrees) (arg +0)
|
||||
MBF_Scratch, // misc1 = damage, misc 2 = sound
|
||||
MBF_PlaySound, // misc1 = sound, misc2 = attenuation none (true) or normal (false)
|
||||
MBF_RandomJump, // misc1 = state, misc2 = probability
|
||||
MBF_LineEffect, // misc1 = Boom linedef type, misc2 = sector tag
|
||||
SMMU_NailBomb, // No misc, but it's basically A_Explode with an added effect
|
||||
CreateMushroomFunc,
|
||||
CreateSpawnFunc,
|
||||
CreateTurnFunc,
|
||||
CreateFaceFunc,
|
||||
CreateScratchFunc,
|
||||
CreatePlaySoundFunc,
|
||||
CreateRandomJumpFunc,
|
||||
CreateLineEffectFunc,
|
||||
CreateNailBombFunc
|
||||
};
|
||||
|
||||
int PrepareStateParameters(FState * state, int numparams, const PClass *cls);// Should probably be in a .h file.
|
||||
// Creates new functions for the given state so as to convert MBF-args (misc1 and misc2) into real args.
|
||||
|
||||
// Hacks the parameter list for the given state so as to convert MBF-args (misc1 and misc2) into real args.
|
||||
|
||||
void SetDehParams(FState * state, int codepointer)
|
||||
void SetDehParams(FState *state, int codepointer)
|
||||
{
|
||||
int value1 = state->GetMisc1();
|
||||
int value2 = state->GetMisc2();
|
||||
|
@ -662,101 +785,36 @@ void SetDehParams(FState * state, int codepointer)
|
|||
// Fakey fake script position thingamajig. Because NULL cannot be used instead.
|
||||
// Even if the lump was parsed by an FScanner, there would hardly be a way to
|
||||
// identify which line is troublesome.
|
||||
FScriptPosition * pos = new FScriptPosition(FString("DEHACKED"), 0);
|
||||
FScriptPosition *pos = new FScriptPosition(FString("DEHACKED"), 0);
|
||||
|
||||
// Let's identify the codepointer we're dealing with.
|
||||
PSymbolActionFunction * sym; PSymbol * s;
|
||||
s = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true);
|
||||
if (!s || s->SymbolType != SYM_ActionFunction) return;
|
||||
sym = static_cast<PSymbolActionFunction*>(s);
|
||||
PFunction *sym;
|
||||
sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
|
||||
if (sym == NULL) return;
|
||||
|
||||
|
||||
// Bleargh! This will all have to be redone once scripting works
|
||||
|
||||
// Not sure exactly why the index for a state is greater by one point than the index for a symbol.
|
||||
DPrintf("SetDehParams: Paramindex is %d, default is %d.\n",
|
||||
state->ParameterIndex-1, sym->defaultparameterindex);
|
||||
if (state->ParameterIndex-1 == sym->defaultparameterindex)
|
||||
if (codepointer < 0 || (unsigned)codepointer >= countof(MBFCodePointerFactories))
|
||||
{
|
||||
int a = PrepareStateParameters(state, MBFCodePointers[codepointer].params+1,
|
||||
FState::StaticFindStateOwner(state)) -1;
|
||||
int b = sym->defaultparameterindex;
|
||||
// StateParams.Copy(a, b, MBFParams[codepointer]);
|
||||
// Meh, function doesn't work. For some reason it resets the paramindex to the default value.
|
||||
// For instance, a dehacked Commander Keen calling A_Explode would result in a crash as
|
||||
// ACTION_PARAM_INT(damage, 0) would properly evaluate at paramindex 1377, but then
|
||||
// ACTION_PARAM_INT(distance, 1) would improperly evaluate at paramindex 148! Now I'm not sure
|
||||
// whether it's a genuine problem or working as intended and merely not appropriate for the
|
||||
// task at hand here. So rather than modify it, I use a simple for loop of Set()s and Get()s,
|
||||
// with a small modification to Set() that I know will have no repercussion anywhere else.
|
||||
for (int i = 0; i<MBFCodePointers[codepointer].params; i++)
|
||||
{
|
||||
StateParams.Set(a+i, StateParams.Get(b+i), true);
|
||||
}
|
||||
DPrintf("New paramindex is %d.\n", state->ParameterIndex-1);
|
||||
}
|
||||
int ParamIndex = state->ParameterIndex - 1;
|
||||
|
||||
switch (codepointer)
|
||||
{
|
||||
case MBF_Mushroom:
|
||||
StateParams.Set(ParamIndex+2, new FxConstant(1, *pos)); // Flag
|
||||
// NOTE: Do not convert to float here because it will lose precision. It must be double.
|
||||
if (value1) StateParams.Set(ParamIndex+3, new FxConstant(value1/65536., *pos)); // vrange
|
||||
if (value2) StateParams.Set(ParamIndex+4, new FxConstant(value2/65536., *pos)); // hrange
|
||||
break;
|
||||
case MBF_Spawn:
|
||||
if (InfoNames[value1-1] == NULL)
|
||||
{
|
||||
I_Error("No class found for dehackednum %d!\n", value1+1);
|
||||
return;
|
||||
}
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(InfoNames[value1-1], *pos)); // type
|
||||
StateParams.Set(ParamIndex+2, new FxConstant(value2, *pos)); // height
|
||||
break;
|
||||
case MBF_Turn:
|
||||
// Intentional fall through. I tried something more complicated by creating an
|
||||
// FxExpression that corresponded to "variable angle + angle" so as to use A_SetAngle
|
||||
// as well, but it became an overcomplicated mess that didn't even work as I had to
|
||||
// create a compile context as well and couldn't get it right.
|
||||
case MBF_Face:
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(value1, *pos)); // angle
|
||||
break;
|
||||
case MBF_Scratch: // misc1 = damage, misc 2 = sound
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(value1, *pos)); // damage
|
||||
if (value2) StateParams.Set(ParamIndex+1, new FxConstant(SoundMap[value2-1], *pos)); // hit sound
|
||||
break;
|
||||
case MBF_PlaySound:
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(SoundMap[value1-1], *pos)); // soundid
|
||||
StateParams.Set(ParamIndex+1, new FxConstant(CHAN_BODY, *pos)); // channel
|
||||
StateParams.Set(ParamIndex+2, new FxConstant(1.0, *pos)); // volume
|
||||
StateParams.Set(ParamIndex+3, new FxConstant(false, *pos)); // looping
|
||||
StateParams.Set(ParamIndex+4, new FxConstant((value2 ? ATTN_NONE : ATTN_NORM), *pos)); // attenuation
|
||||
break;
|
||||
case MBF_RandomJump:
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(2, *pos)); // count
|
||||
StateParams.Set(ParamIndex+1, new FxConstant(value2, *pos)); // maxchance
|
||||
StateParams.Set(ParamIndex+2, new FxConstant(FindState(value1), *pos)); // jumpto
|
||||
break;
|
||||
case MBF_LineEffect:
|
||||
// This is the second MBF codepointer that couldn't be translated easily.
|
||||
// Calling P_TranslateLineDef() here was a simple matter, as was adding an
|
||||
// extra parameter to A_CallSpecial so as to replicate the LINEDONE stuff,
|
||||
// but unfortunately DEHACKED lumps are processed before the map translation
|
||||
// arrays are initialized so this didn't work.
|
||||
StateParams.Set(ParamIndex+0, new FxConstant(value1, *pos)); // special
|
||||
StateParams.Set(ParamIndex+1, new FxConstant(value2, *pos)); // tag
|
||||
break;
|
||||
case SMMU_NailBomb:
|
||||
// That one does not actually have MBF-style parameters. But since
|
||||
// we're aliasing it to an extension of A_Explode...
|
||||
StateParams.Set(ParamIndex+5, new FxConstant(30, *pos)); // nails
|
||||
StateParams.Set(ParamIndex+6, new FxConstant(10, *pos)); // naildamage
|
||||
break;
|
||||
default:
|
||||
// This simply should not happen.
|
||||
Printf("Unmanaged dehacked codepointer alias num %i\n", codepointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
VMFunctionBuilder buildit;
|
||||
// Allocate registers used to pass parameters in.
|
||||
// self, stateowner, state (all are pointers)
|
||||
buildit.Registers[REGT_POINTER].Get(3);
|
||||
// Emit code to pass the standard action function parameters.
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 0);
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 1);
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 2);
|
||||
// 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);
|
||||
// Attach it to the state.
|
||||
VMScriptFunction *sfunc = buildit.MakeFunction();
|
||||
sfunc->NumArgs = NAP;
|
||||
state->SetAction(sfunc);
|
||||
}
|
||||
}
|
||||
|
||||
static int PatchThing (int thingy)
|
||||
|
@ -785,7 +843,7 @@ static int PatchThing (int thingy)
|
|||
FStateDefinitions statedef;
|
||||
bool patchedStates = false;
|
||||
ActorFlags oldflags;
|
||||
const PClass *type;
|
||||
PClassActor *type;
|
||||
SWORD *ednum, dummyed;
|
||||
|
||||
type = NULL;
|
||||
|
@ -811,7 +869,7 @@ static int PatchThing (int thingy)
|
|||
else
|
||||
{
|
||||
info = GetDefaultByType (type);
|
||||
ednum = &type->ActorInfo->DoomEdNum;
|
||||
ednum = &type->DoomEdNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -851,7 +909,7 @@ static int PatchThing (int thingy)
|
|||
}
|
||||
else if (linelen == 14 && stricmp (Line1, "Missile damage") == 0)
|
||||
{
|
||||
info->Damage = val;
|
||||
info->Damage = CreateDamageFunction(val);
|
||||
}
|
||||
else if (linelen == 5)
|
||||
{
|
||||
|
@ -1227,7 +1285,7 @@ static int PatchThing (int thingy)
|
|||
|
||||
if (info->flags & MF_SPECIAL)
|
||||
{
|
||||
PushTouchedActor(const_cast<PClass *>(type));
|
||||
PushTouchedActor(const_cast<PClassActor *>(type));
|
||||
}
|
||||
|
||||
// If MF_COUNTKILL is set, make sure the other standard monster flags are
|
||||
|
@ -1250,7 +1308,7 @@ static int PatchThing (int thingy)
|
|||
info->flags4 |= MF4_CANUSEWALLS;
|
||||
if (patchedStates)
|
||||
{
|
||||
statedef.InstallStates(type->ActorInfo, info);
|
||||
statedef.InstallStates(type, info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1520,7 @@ static int PatchSprite (int sprNum)
|
|||
|
||||
static int PatchAmmo (int ammoNum)
|
||||
{
|
||||
const PClass *ammoType = NULL;
|
||||
PClassAmmo *ammoType = NULL;
|
||||
AAmmo *defaultAmmo = NULL;
|
||||
int result;
|
||||
int oldclip;
|
||||
|
@ -1509,9 +1567,9 @@ static int PatchAmmo (int ammoNum)
|
|||
// Fix per-ammo/max-ammo amounts for descendants of the base ammo class
|
||||
if (oldclip != *per)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
PClass *type = PClass::m_Types[i];
|
||||
PClassActor *type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type == ammoType)
|
||||
continue;
|
||||
|
@ -1543,7 +1601,7 @@ static int PatchAmmo (int ammoNum)
|
|||
static int PatchWeapon (int weapNum)
|
||||
{
|
||||
int result;
|
||||
const PClass *type = NULL;
|
||||
PClassActor *type = NULL;
|
||||
BYTE dummy[sizeof(AWeapon)];
|
||||
AWeapon *info = (AWeapon *)&dummy;
|
||||
bool patchedStates = false;
|
||||
|
@ -1647,28 +1705,26 @@ static int PatchWeapon (int weapNum)
|
|||
|
||||
if (patchedStates)
|
||||
{
|
||||
statedef.InstallStates(type->ActorInfo, info);
|
||||
statedef.InstallStates(type, info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void SetPointer(FState *state, PSymbol *sym, int frame = 0)
|
||||
static void SetPointer(FState *state, PFunction *sym, int frame = 0)
|
||||
{
|
||||
if (sym==NULL || sym->SymbolType != SYM_ActionFunction)
|
||||
if (sym == NULL)
|
||||
{
|
||||
state->SetAction(NULL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
FString symname = sym->SymbolName.GetChars();
|
||||
state->SetAction(static_cast<PSymbolActionFunction*>(sym));
|
||||
state->SetAction(sym->Variants[0].Implementation);
|
||||
|
||||
// Note: CompareNoCase() calls stricmp() and therefore returns 0 when they're the same.
|
||||
for (unsigned int i = 0; i < MBFCodePointers.Size(); i++)
|
||||
{
|
||||
if (!symname.CompareNoCase(MBFCodePointers[i].name))
|
||||
if (sym->SymbolName == MBFCodePointers[i].name)
|
||||
{
|
||||
MBFParamState newstate;
|
||||
newstate.state = state;
|
||||
|
@ -1722,7 +1778,9 @@ static int PatchPointer (int ptrNum)
|
|||
{
|
||||
int index = atoi(Line2);
|
||||
if ((unsigned)(index) >= Actions.Size())
|
||||
{
|
||||
SetPointer(state, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPointer(state, Actions[index], CodePConv[ptrNum]);
|
||||
|
@ -1820,16 +1878,16 @@ static int PatchMisc (int dummy)
|
|||
"Minotaur",
|
||||
NULL
|
||||
};
|
||||
static const PClass * const types[] =
|
||||
static const PClass * const *types[] =
|
||||
{
|
||||
RUNTIME_CLASS(APowerInvulnerable),
|
||||
RUNTIME_CLASS(APowerStrength),
|
||||
RUNTIME_CLASS(APowerInvisibility),
|
||||
RUNTIME_CLASS(APowerIronFeet),
|
||||
RUNTIME_CLASS(APowerLightAmp),
|
||||
RUNTIME_CLASS(APowerWeaponLevel2),
|
||||
RUNTIME_CLASS(APowerSpeed),
|
||||
RUNTIME_CLASS(APowerMinotaur)
|
||||
&RUNTIME_CLASS_CASTLESS(APowerInvulnerable),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerStrength),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerInvisibility),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerIronFeet),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerLightAmp),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerWeaponLevel2),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerSpeed),
|
||||
&RUNTIME_CLASS_CASTLESS(APowerMinotaur)
|
||||
};
|
||||
int i;
|
||||
|
||||
|
@ -1855,7 +1913,7 @@ static int PatchMisc (int dummy)
|
|||
}
|
||||
else if (a > 0)
|
||||
{
|
||||
static_cast<APowerup *>(GetDefaultByType (types[i]))->BlendColor = PalEntry(
|
||||
static_cast<APowerup *>(GetDefaultByType (*types[i]))->BlendColor = PalEntry(
|
||||
BYTE(clamp(a,0.f,1.f)*255.f),
|
||||
clamp(r,0,255),
|
||||
clamp(g,0,255),
|
||||
|
@ -1863,7 +1921,7 @@ static int PatchMisc (int dummy)
|
|||
}
|
||||
else
|
||||
{
|
||||
static_cast<APowerup *>(GetDefaultByType (types[i]))->BlendColor = 0;
|
||||
static_cast<APowerup *>(GetDefaultByType (*types[i]))->BlendColor = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1924,18 +1982,14 @@ static int PatchMisc (int dummy)
|
|||
player->health = deh.StartHealth;
|
||||
|
||||
// Hm... I'm not sure that this is the right way to change this info...
|
||||
int index = PClass::FindClass(NAME_DoomPlayer)->Meta.GetMetaInt (ACMETA_DropItems) - 1;
|
||||
if (index >= 0 && index < (signed)DropItemList.Size())
|
||||
DDropItem *di = PClass::FindActor(NAME_DoomPlayer)->DropItems;
|
||||
while (di != NULL)
|
||||
{
|
||||
FDropItem * di = DropItemList[index];
|
||||
while (di != NULL)
|
||||
if (di->Name == NAME_Clip)
|
||||
{
|
||||
if (di->Name == NAME_Clip)
|
||||
{
|
||||
di->amount = deh.StartBullets;
|
||||
}
|
||||
di = di->Next;
|
||||
di->Amount = deh.StartBullets;
|
||||
}
|
||||
di = di->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2043,21 +2097,21 @@ 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);
|
||||
Printf("%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.
|
||||
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true);
|
||||
if (sym == NULL || sym->SymbolType != SYM_ActionFunction)
|
||||
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true));
|
||||
if (sym == NULL)
|
||||
{
|
||||
Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments;
|
||||
if (args.Len()!=0 && (args[0]<'a' || args[0]>'z'))
|
||||
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
|
||||
if (args.Size() != 0 && !(args[0] & VARF_Optional))
|
||||
{
|
||||
Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
|
||||
sym = NULL;
|
||||
|
@ -2541,25 +2595,6 @@ static inline bool CompareLabel (const char *want, const BYTE *have)
|
|||
return *(DWORD *)want == *(DWORD *)have;
|
||||
}
|
||||
|
||||
static inline short GetWord (const BYTE *in)
|
||||
{
|
||||
return (in[0] << 8) | (in[1]);
|
||||
}
|
||||
|
||||
static short *GetWordSpace (void *in, size_t size)
|
||||
{
|
||||
short *ptr;
|
||||
size_t i;
|
||||
|
||||
ptr = (short *)in;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
ptr[i] = GetWord ((BYTE *)in + i*2);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int DehUseCount;
|
||||
|
||||
static void UnloadDehSupp ()
|
||||
|
@ -2680,15 +2715,15 @@ static bool LoadDehSupp ()
|
|||
// or AActor so this will find all of them.
|
||||
FString name = "A_";
|
||||
name << sc.String;
|
||||
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true);
|
||||
if (sym == NULL || sym->SymbolType != SYM_ActionFunction)
|
||||
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true));
|
||||
if (sym == NULL)
|
||||
{
|
||||
sc.ScriptError("Unknown code pointer '%s'", sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments;
|
||||
if (args.Len()!=0 && (args[0]<'a' || args[0]>'z'))
|
||||
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
|
||||
if (args.Size() != 0 && !(args[0] & VARF_Optional))
|
||||
{
|
||||
sc.ScriptError("Incompatible code pointer '%s'", sc.String);
|
||||
}
|
||||
|
@ -2757,19 +2792,20 @@ static bool LoadDehSupp ()
|
|||
StateMapper s;
|
||||
sc.MustGetString();
|
||||
|
||||
const PClass *type = PClass::FindClass (sc.String);
|
||||
PClass *type = PClass::FindClass (sc.String);
|
||||
if (type == NULL)
|
||||
{
|
||||
sc.ScriptError ("Can't find type %s", sc.String);
|
||||
}
|
||||
else if (type->ActorInfo == NULL)
|
||||
else if (!type->IsKindOf(RUNTIME_CLASS(PClassActor)))
|
||||
{
|
||||
sc.ScriptError ("%s has no ActorInfo", sc.String);
|
||||
sc.ScriptError ("%s is not an actor", sc.String);
|
||||
}
|
||||
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
s.State = type->ActorInfo->FindState(sc.String);
|
||||
PClassActor *actortype = static_cast<PClassActor *>(type);
|
||||
s.State = actortype->FindState(sc.String);
|
||||
if (s.State == NULL)
|
||||
{
|
||||
sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
|
||||
|
@ -2777,14 +2813,14 @@ static bool LoadDehSupp ()
|
|||
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
if (s.State == NULL || s.State + sc.Number > type->ActorInfo->OwnedStates + type->ActorInfo->NumOwnedStates)
|
||||
if (s.State == NULL || s.State + sc.Number > actortype->OwnedStates + actortype->NumOwnedStates)
|
||||
{
|
||||
sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
|
||||
}
|
||||
AActor *def = GetDefaultByType(type);
|
||||
|
||||
s.StateSpan = sc.Number;
|
||||
s.Owner = type;
|
||||
s.Owner = actortype;
|
||||
s.OwnerIsPickup = def != NULL && (def->flags & MF_SPECIAL) != 0;
|
||||
if (addit) StateMap.Push(s);
|
||||
|
||||
|
@ -2809,7 +2845,7 @@ static bool LoadDehSupp ()
|
|||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
const PClass *cls = PClass::FindClass(sc.String);
|
||||
PClassActor *cls = PClass::FindActor(sc.String);
|
||||
if (cls == NULL)
|
||||
{
|
||||
sc.ScriptError("Unknown actor type '%s'", sc.String);
|
||||
|
@ -2876,8 +2912,8 @@ static bool LoadDehSupp ()
|
|||
}
|
||||
else
|
||||
{
|
||||
const PClass *cls = PClass::FindClass(sc.String);
|
||||
if (cls == NULL || cls->ParentClass != RUNTIME_CLASS(AAmmo))
|
||||
PClassAmmo *cls = dyn_cast<PClassAmmo>(PClass::FindClass(sc.String));
|
||||
if (cls == NULL)
|
||||
{
|
||||
sc.ScriptError("Unknown ammo type '%s'", sc.String);
|
||||
}
|
||||
|
@ -2894,12 +2930,12 @@ static bool LoadDehSupp ()
|
|||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
const PClass *cls = PClass::FindClass(sc.String);
|
||||
PClass *cls = PClass::FindClass(sc.String);
|
||||
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
sc.ScriptError("Unknown weapon type '%s'", sc.String);
|
||||
}
|
||||
WeaponNames.Push(cls);
|
||||
WeaponNames.Push(static_cast<PClassActor *>(cls));
|
||||
if (sc.CheckString("}")) break;
|
||||
sc.MustGetStringName(",");
|
||||
}
|
||||
|
@ -2915,8 +2951,7 @@ static bool LoadDehSupp ()
|
|||
temp.alias[19]=0;
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
strncpy(temp.name, sc.String, 19);
|
||||
temp.name[19]=0;
|
||||
temp.name = sc.String;
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
temp.params = sc.Number;
|
||||
|
@ -2949,7 +2984,7 @@ void FinishDehPatch ()
|
|||
|
||||
for (touchedIndex = 0; touchedIndex < TouchedActors.Size(); ++touchedIndex)
|
||||
{
|
||||
PClass *type = TouchedActors[touchedIndex];
|
||||
PClassActor *type = TouchedActors[touchedIndex];
|
||||
AActor *defaults1 = GetDefaultByType (type);
|
||||
if (!(defaults1->flags & MF_SPECIAL))
|
||||
{ // We only need to do this for pickups
|
||||
|
@ -2959,8 +2994,8 @@ void FinishDehPatch ()
|
|||
// Create a new class that will serve as the actual pickup
|
||||
char typeNameBuilder[32];
|
||||
mysnprintf (typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", touchedIndex);
|
||||
PClass *subclass = RUNTIME_CLASS(ADehackedPickup)->CreateDerivedClass
|
||||
(typeNameBuilder, sizeof(ADehackedPickup));
|
||||
PClassActor *subclass = static_cast<PClassActor *>(RUNTIME_CLASS(ADehackedPickup)->
|
||||
CreateDerivedClass(typeNameBuilder, sizeof(ADehackedPickup)));
|
||||
AActor *defaults2 = GetDefaultByType (subclass);
|
||||
memcpy ((void *)defaults2, (void *)defaults1, sizeof(AActor));
|
||||
|
||||
|
@ -2971,21 +3006,21 @@ void FinishDehPatch ()
|
|||
if (!type->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
// If this is a hacked non-inventory item we must also copy AInventory's special states
|
||||
statedef.AddStateDefines(RUNTIME_CLASS(AInventory)->ActorInfo->StateList);
|
||||
statedef.AddStateDefines(RUNTIME_CLASS(AInventory)->StateList);
|
||||
}
|
||||
statedef.InstallStates(subclass->ActorInfo, defaults2);
|
||||
statedef.InstallStates(subclass, defaults2);
|
||||
|
||||
// Use the DECORATE replacement feature to redirect all spawns
|
||||
// of the original class to the new one.
|
||||
FActorInfo *old_replacement = type->ActorInfo->Replacement;
|
||||
PClassActor *old_replacement = type->Replacement;
|
||||
|
||||
type->ActorInfo->Replacement = subclass->ActorInfo;
|
||||
subclass->ActorInfo->Replacee = type->ActorInfo;
|
||||
type->Replacement = subclass;
|
||||
subclass->Replacee = type;
|
||||
// If this actor was already replaced by another actor, copy that
|
||||
// replacement over to this item.
|
||||
if (old_replacement != NULL)
|
||||
{
|
||||
subclass->ActorInfo->Replacement = old_replacement;
|
||||
subclass->Replacement = old_replacement;
|
||||
}
|
||||
|
||||
DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars());
|
||||
|
@ -3018,7 +3053,7 @@ void FinishDehPatch ()
|
|||
|
||||
TMap<FState*, bool> StateVisited;
|
||||
|
||||
FState *state = WeaponNames[i]->ActorInfo->FindState(NAME_Fire);
|
||||
FState *state = WeaponNames[i]->FindState(NAME_Fire);
|
||||
while (state != NULL)
|
||||
{
|
||||
bool *check = StateVisited.CheckKey(state);
|
||||
|
@ -3029,7 +3064,7 @@ void FinishDehPatch ()
|
|||
StateVisited[state] = true;
|
||||
for(unsigned j = 0; AmmoPerAttacks[j].func != NULL; j++)
|
||||
{
|
||||
if (state->ActionFunc == AmmoPerAttacks[j].func)
|
||||
if (state->ActionFunc == *AmmoPerAttacks[j].func)
|
||||
{
|
||||
found = true;
|
||||
int use = AmmoPerAttacks[j].ammocount;
|
||||
|
@ -3051,7 +3086,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount);
|
|||
|
||||
bool ADehackedPickup::TryPickup (AActor *&toucher)
|
||||
{
|
||||
const PClass *type = DetermineType ();
|
||||
PClassActor *type = DetermineType ();
|
||||
if (type == NULL)
|
||||
{
|
||||
return false;
|
||||
|
@ -3125,7 +3160,7 @@ void ADehackedPickup::Destroy ()
|
|||
Super::Destroy ();
|
||||
}
|
||||
|
||||
const PClass *ADehackedPickup::DetermineType ()
|
||||
PClassActor *ADehackedPickup::DetermineType ()
|
||||
{
|
||||
// Look at the actor's current sprite to determine what kind of
|
||||
// item to pretend to me.
|
||||
|
@ -3138,7 +3173,7 @@ const PClass *ADehackedPickup::DetermineType ()
|
|||
int lex = memcmp (DehSpriteMappings[mid].Sprite, sprites[sprite].name, 4);
|
||||
if (lex == 0)
|
||||
{
|
||||
return PClass::FindClass (DehSpriteMappings[mid].ClassName);
|
||||
return PClass::FindActor(DehSpriteMappings[mid].ClassName);
|
||||
}
|
||||
else if (lex < 0)
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
void DoPickupSpecial (AActor *toucher);
|
||||
void Serialize(FArchive &arc);
|
||||
private:
|
||||
const PClass *DetermineType ();
|
||||
PClassActor *DetermineType ();
|
||||
AInventory *RealPickup;
|
||||
public:
|
||||
bool droppedbymonster;
|
||||
|
|
|
@ -107,6 +107,8 @@
|
|||
#include "resourcefiles/resourcefile.h"
|
||||
#include "r_renderer.h"
|
||||
#include "p_local.h"
|
||||
#include "autosegs.h"
|
||||
#include "fragglescript/t_fs.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
void DrawHUD();
|
||||
|
@ -1930,6 +1932,22 @@ static void SetMapxxFlag()
|
|||
if (lump_name >= 0 || lump_wad >= 0 || lump_map >= 0) gameinfo.flags |= GI_MAPxx;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FinalGC
|
||||
//
|
||||
// If this doesn't free everything, the debug CRT will let us know.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void FinalGC()
|
||||
{
|
||||
Args = NULL;
|
||||
GC::FinalGC = true;
|
||||
GC::FullGC();
|
||||
GC::DelSoftRootHead(); // the soft root head will not be collected by a GC so we have to do it explicitly
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initialize
|
||||
|
@ -1958,6 +1976,8 @@ static void D_DoomInit()
|
|||
// Check response files before coalescing file parameters.
|
||||
M_FindResponseFile ();
|
||||
|
||||
atterm(FinalGC);
|
||||
|
||||
// Combine different file parameters with their pre-switch bits.
|
||||
Args->CollectFiles("-deh", ".deh");
|
||||
Args->CollectFiles("-bex", ".bex");
|
||||
|
@ -2178,21 +2198,6 @@ static void CheckCmdLine()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FinalGC
|
||||
//
|
||||
// If this doesn't free everything, the debug CRT will let us know.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void FinalGC()
|
||||
{
|
||||
Args = NULL;
|
||||
GC::FullGC();
|
||||
GC::DelSoftRootHead(); // the soft root head will not be collected by a GC so we have to do it explicitly
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D_DoomMain
|
||||
|
@ -2241,7 +2246,6 @@ void D_DoomMain (void)
|
|||
|
||||
// [RH] Make sure zdoom.pk3 is always loaded,
|
||||
// as it contains magic stuff we need.
|
||||
|
||||
wad = BaseFileSearch (BASEWAD, NULL, true);
|
||||
if (wad == NULL)
|
||||
{
|
||||
|
@ -2255,13 +2259,13 @@ void D_DoomMain (void)
|
|||
// Now that we have the IWADINFO, initialize the autoload ini sections.
|
||||
GameConfig->DoAutoloadSetup(iwad_man);
|
||||
|
||||
PClass::StaticInit ();
|
||||
atterm(FinalGC);
|
||||
|
||||
// reinit from here
|
||||
|
||||
do
|
||||
{
|
||||
PClass::StaticInit();
|
||||
PType::StaticInit();
|
||||
|
||||
if (restart)
|
||||
{
|
||||
C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false);
|
||||
|
@ -2409,12 +2413,11 @@ void D_DoomMain (void)
|
|||
Printf ("ParseTeamInfo: Load team definitions.\n");
|
||||
TeamLibrary.ParseTeamInfo ();
|
||||
|
||||
FActorInfo::StaticInit ();
|
||||
PClassActor::StaticInit ();
|
||||
|
||||
// [GRB] Initialize player class list
|
||||
SetupPlayerClasses ();
|
||||
|
||||
|
||||
// [RH] Load custom key and weapon settings from WADs
|
||||
D_LoadWadSettings ();
|
||||
|
||||
|
@ -2460,9 +2463,8 @@ void D_DoomMain (void)
|
|||
FinishDehPatch();
|
||||
|
||||
InitActorNumsFromMapinfo();
|
||||
PClassActor::StaticSetActorNums ();
|
||||
InitSpawnablesFromMapinfo();
|
||||
FActorInfo::StaticSetActorNums ();
|
||||
|
||||
//Added by MC:
|
||||
bglobal.getspawned.Clear();
|
||||
argcount = Args->CheckParmList("-bots", &args);
|
||||
|
@ -2639,9 +2641,28 @@ void D_DoomMain (void)
|
|||
C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here
|
||||
DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods
|
||||
|
||||
GC::FullGC(); // perform one final garbage collection before deleting the class data
|
||||
PClass::ClearRuntimeData(); // clear all runtime generated class data
|
||||
GC::FullGC(); // clean up before taking down the object list.
|
||||
|
||||
// Delete the VM functions here. The garbage collector will not do this automatically because they are referenced from the global action function definitions.
|
||||
FAutoSegIterator probe(ARegHead, ARegTail);
|
||||
while (*++probe != NULL)
|
||||
{
|
||||
AFuncDesc *afunc = (AFuncDesc *)*probe;
|
||||
*(afunc->VMPointer) = NULL;
|
||||
}
|
||||
|
||||
ReleaseGlobalSymbols();
|
||||
PClass::StaticShutdown();
|
||||
|
||||
GC::FullGC(); // perform one final garbage collection after shutdown
|
||||
|
||||
for (DObject *obj = GC::Root; obj; obj = obj->ObjNext)
|
||||
{
|
||||
obj->ClearClass(); // Delete the Class pointer because the data it points to has been deleted. This will automatically be reset if needed.
|
||||
}
|
||||
|
||||
restart++;
|
||||
PClass::bShutdown = false;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
|
|
@ -2071,7 +2071,7 @@ BYTE *FDynamicBuffer::GetData (int *len)
|
|||
}
|
||||
|
||||
|
||||
static int KillAll(const PClass *cls)
|
||||
static int KillAll(PClassActor *cls)
|
||||
{
|
||||
AActor *actor;
|
||||
int killcount = 0;
|
||||
|
@ -2291,7 +2291,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
case DEM_SUMMONFRIEND2:
|
||||
case DEM_SUMMONFOE2:
|
||||
{
|
||||
const PClass *typeinfo;
|
||||
PClassActor *typeinfo;
|
||||
int angle = 0;
|
||||
SWORD tid = 0;
|
||||
BYTE special = 0;
|
||||
|
@ -2306,8 +2306,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
for(i = 0; i < 5; i++) args[i] = ReadLong(stream);
|
||||
}
|
||||
|
||||
typeinfo = PClass::FindClass (s);
|
||||
if (typeinfo != NULL && typeinfo->ActorInfo != NULL)
|
||||
typeinfo = PClass::FindActor(s);
|
||||
if (typeinfo != NULL)
|
||||
{
|
||||
AActor *source = players[player].mo;
|
||||
if (source != NULL)
|
||||
|
@ -2503,7 +2503,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
|
||||
case DEM_RUNSPECIAL:
|
||||
{
|
||||
int snum = ReadByte(stream);
|
||||
int snum = ReadWord(stream);
|
||||
int argn = ReadByte(stream);
|
||||
int arg[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
|
@ -2534,7 +2534,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
case DEM_MORPHEX:
|
||||
{
|
||||
s = ReadString (stream);
|
||||
const char *msg = cht_Morph (players + player, PClass::FindClass (s), false);
|
||||
const char *msg = cht_Morph (players + player, dyn_cast<PClassPlayerPawn>(PClass::FindClass (s)), false);
|
||||
if (player == consoleplayer)
|
||||
{
|
||||
Printf ("%s\n", *msg != '\0' ? msg : "Morph failed.");
|
||||
|
@ -2566,12 +2566,12 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
{
|
||||
char *classname = ReadString (stream);
|
||||
int killcount = 0;
|
||||
const PClass *cls = PClass::FindClass(classname);
|
||||
PClassActor *cls = PClass::FindActor(classname);
|
||||
|
||||
if (cls != NULL && cls->ActorInfo != NULL)
|
||||
if (cls != NULL)
|
||||
{
|
||||
killcount = KillAll(cls);
|
||||
const PClass *cls_rep = cls->GetReplacement();
|
||||
PClassActor *cls_rep = cls->GetReplacement();
|
||||
if (cls != cls_rep)
|
||||
{
|
||||
killcount += KillAll(cls_rep);
|
||||
|
@ -2589,8 +2589,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
{
|
||||
char *classname = ReadString(stream);
|
||||
int removecount = 0;
|
||||
const PClass *cls = PClass::FindClass(classname);
|
||||
if (cls != NULL && cls->ActorInfo != NULL)
|
||||
PClassActor *cls = PClass::FindActor(classname);
|
||||
if (cls != NULL && cls->IsKindOf(RUNTIME_CLASS(PClassActor)))
|
||||
{
|
||||
removecount = RemoveClass(cls);
|
||||
const PClass *cls_rep = cls->GetReplacement();
|
||||
|
@ -2633,7 +2633,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
}
|
||||
for(i = 0; i < count; ++i)
|
||||
{
|
||||
const PClass *wpn = Net_ReadWeapon(stream);
|
||||
PClassWeapon *wpn = Net_ReadWeapon(stream);
|
||||
players[pnum].weapons.AddSlot(slot, wpn, pnum == consoleplayer);
|
||||
}
|
||||
}
|
||||
|
@ -2642,7 +2642,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
case DEM_ADDSLOT:
|
||||
{
|
||||
int slot = ReadByte(stream);
|
||||
const PClass *wpn = Net_ReadWeapon(stream);
|
||||
PClassWeapon *wpn = Net_ReadWeapon(stream);
|
||||
players[player].weapons.AddSlot(slot, wpn, player == consoleplayer);
|
||||
}
|
||||
break;
|
||||
|
@ -2650,7 +2650,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
case DEM_ADDSLOTDEFAULT:
|
||||
{
|
||||
int slot = ReadByte(stream);
|
||||
const PClass *wpn = Net_ReadWeapon(stream);
|
||||
PClassWeapon *wpn = Net_ReadWeapon(stream);
|
||||
players[player].weapons.AddSlotDefault(slot, wpn, player == consoleplayer);
|
||||
}
|
||||
break;
|
||||
|
@ -2799,7 +2799,7 @@ void Net_SkipCommand (int type, BYTE **stream)
|
|||
break;
|
||||
|
||||
case DEM_RUNSPECIAL:
|
||||
skip = 2 + *(*stream + 1) * 4;
|
||||
skip = 3 + *(*stream + 2) * 4;
|
||||
break;
|
||||
|
||||
case DEM_CONVREPLY:
|
||||
|
|
|
@ -154,9 +154,9 @@ int D_PlayerClassToInt (const char *classname)
|
|||
{
|
||||
for (unsigned int i = 0; i < PlayerClasses.Size (); ++i)
|
||||
{
|
||||
const PClass *type = PlayerClasses[i].Type;
|
||||
PClassPlayerPawn *type = PlayerClasses[i].Type;
|
||||
|
||||
if (stricmp (type->Meta.GetMetaString (APMETA_DisplayName), classname) == 0)
|
||||
if (type->DisplayName.IsNotEmpty() && stricmp(type->DisplayName, classname) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet
|
|||
|
||||
if (players[player].mo != NULL)
|
||||
{
|
||||
colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->GetColorSet());
|
||||
colorset = players[player].mo->GetClass()->GetColorSet(info->GetColorSet());
|
||||
}
|
||||
if (colorset != NULL)
|
||||
{
|
||||
|
@ -723,7 +723,7 @@ void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact)
|
|||
|
||||
case NAME_PlayerClass:
|
||||
*stream += sprintf(*((char **)stream), "\\%s", info->GetPlayerClassNum() == -1 ? "Random" :
|
||||
D_EscapeUserInfo(info->GetPlayerClassType()->Meta.GetMetaString(APMETA_DisplayName)).GetChars());
|
||||
D_EscapeUserInfo(info->GetPlayerClassType()->DisplayName.GetChars()).GetChars());
|
||||
break;
|
||||
|
||||
case NAME_Skin:
|
||||
|
@ -925,7 +925,7 @@ void WriteUserInfo(FArchive &arc, userinfo_t &info)
|
|||
|
||||
case NAME_PlayerClass:
|
||||
i = info.GetPlayerClassNum();
|
||||
arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->Meta.GetMetaString(APMETA_DisplayName));
|
||||
arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->DisplayName.GetChars());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1014,7 +1014,7 @@ CCMD (playerinfo)
|
|||
Printf("%20s: %s (%d)\n", "Skin", skins[ui->GetSkin()].name, ui->GetSkin());
|
||||
Printf("%20s: %s (%d)\n", "Gender", GenderNames[ui->GetGender()], ui->GetGender());
|
||||
Printf("%20s: %s (%d)\n", "PlayerClass",
|
||||
ui->GetPlayerClassNum() == -1 ? "Random" : ui->GetPlayerClassType()->Meta.GetMetaString (APMETA_DisplayName),
|
||||
ui->GetPlayerClassNum() == -1 ? "Random" : ui->GetPlayerClassType()->DisplayName.GetChars(),
|
||||
ui->GetPlayerClassNum());
|
||||
|
||||
// Print generic info
|
||||
|
|
|
@ -44,41 +44,61 @@
|
|||
//Added by MC:
|
||||
#include "b_bot.h"
|
||||
|
||||
enum
|
||||
{
|
||||
APMETA_BASE = 0x95000,
|
||||
class player_t;
|
||||
|
||||
APMETA_DisplayName, // display name (used in menus etc.)
|
||||
APMETA_SoundClass, // sound class
|
||||
APMETA_Face, // doom status bar face (when used)
|
||||
APMETA_ColorRange, // skin color range
|
||||
APMETA_InvulMode,
|
||||
APMETA_HealingRadius,
|
||||
APMETA_Portrait,
|
||||
APMETA_Hexenarmor0,
|
||||
APMETA_Hexenarmor1,
|
||||
APMETA_Hexenarmor2,
|
||||
APMETA_Hexenarmor3,
|
||||
APMETA_Hexenarmor4,
|
||||
APMETA_Slot0,
|
||||
APMETA_Slot1,
|
||||
APMETA_Slot2,
|
||||
APMETA_Slot3,
|
||||
APMETA_Slot4,
|
||||
APMETA_Slot5,
|
||||
APMETA_Slot6,
|
||||
APMETA_Slot7,
|
||||
APMETA_Slot8,
|
||||
APMETA_Slot9,
|
||||
// Standard pre-defined skin colors
|
||||
struct FPlayerColorSet
|
||||
{
|
||||
struct ExtraRange
|
||||
{
|
||||
BYTE RangeStart, RangeEnd; // colors to remap
|
||||
BYTE FirstColor, LastColor; // colors to map to
|
||||
};
|
||||
|
||||
FName Name; // Name of this color
|
||||
|
||||
int Lump; // Lump to read the translation from, otherwise use next 2 fields
|
||||
BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation
|
||||
|
||||
BYTE RepresentativeColor; // A palette entry representative of this translation,
|
||||
// for map arrows and status bar backgrounds and such
|
||||
BYTE NumExtraRanges;
|
||||
ExtraRange Extra[6];
|
||||
};
|
||||
|
||||
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum);
|
||||
void P_EnumPlayerColorSets(FName classname, TArray<int> *out);
|
||||
const char *GetPrintableDisplayName(const PClass *cls);
|
||||
typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
|
||||
typedef TMap<FName, PalEntry> PainFlashList;
|
||||
|
||||
class PClassPlayerPawn : public PClassActor
|
||||
{
|
||||
DECLARE_CLASS(PClassPlayerPawn, PClassActor);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassPlayerPawn();
|
||||
void EnumColorSets(TArray<int> *out);
|
||||
FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
|
||||
void SetPainFlash(FName type, PalEntry color);
|
||||
bool GetPainFlash(FName type, PalEntry *color) const;
|
||||
|
||||
FString DisplayName; // Display name (used in menus, etc.)
|
||||
FString SoundClass; // Sound class
|
||||
FString Face; // Doom status bar face (when used)
|
||||
FString Portrait;
|
||||
FString Slot[10];
|
||||
FName InvulMode;
|
||||
FName HealingRadiusType;
|
||||
fixed_t HexenArmor[5];
|
||||
BYTE ColorRangeStart; // Skin color range
|
||||
BYTE ColorRangeEnd;
|
||||
FPlayerColorSetMap ColorSets;
|
||||
PainFlashList PainFlashes;
|
||||
};
|
||||
FString GetPrintableDisplayName(PClassPlayerPawn *cls);
|
||||
|
||||
class APlayerPawn : public AActor
|
||||
{
|
||||
DECLARE_CLASS (APlayerPawn, AActor)
|
||||
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
virtual void Serialize (FArchive &arc);
|
||||
|
@ -96,9 +116,9 @@ public:
|
|||
virtual void TweakSpeeds (int &forwardmove, int &sidemove);
|
||||
virtual void MorphPlayerThink ();
|
||||
virtual void ActivateMorphWeapon ();
|
||||
AWeapon *PickNewWeapon (const PClass *ammotype);
|
||||
AWeapon *BestWeapon (const PClass *ammotype);
|
||||
void CheckWeaponSwitch(const PClass *ammotype);
|
||||
AWeapon *PickNewWeapon (PClassAmmo *ammotype);
|
||||
AWeapon *BestWeapon (PClassAmmo *ammotype);
|
||||
void CheckWeaponSwitch(PClassAmmo *ammotype);
|
||||
virtual void GiveDeathmatchInventory ();
|
||||
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
|
||||
|
||||
|
@ -140,7 +160,8 @@ public:
|
|||
fixed_t AttackZOffset; // attack height, relative to player center
|
||||
fixed_t UseRange; // [NS] Distance at which player can +use
|
||||
fixed_t AirCapacity; // Multiplier for air supply underwater.
|
||||
const PClass *FlechetteType;
|
||||
PClassActor *FlechetteType;
|
||||
|
||||
|
||||
// [CW] Fades for when you are being damaged.
|
||||
PalEntry DamageFade;
|
||||
|
@ -251,7 +272,7 @@ public:
|
|||
|
||||
bool CheckSkin (int skin);
|
||||
|
||||
const PClass *Type;
|
||||
PClassPlayerPawn *Type;
|
||||
DWORD Flags;
|
||||
TArray<int> Skins;
|
||||
};
|
||||
|
@ -319,7 +340,7 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
|
|||
{
|
||||
return *static_cast<FIntCVar *>(*CheckKey(NAME_PlayerClass));
|
||||
}
|
||||
const PClass *GetPlayerClassType() const
|
||||
PClassPlayerPawn *GetPlayerClassType() const
|
||||
{
|
||||
return PlayerClasses[GetPlayerClassNum()].Type;
|
||||
}
|
||||
|
@ -376,7 +397,7 @@ public:
|
|||
|
||||
userinfo_t userinfo; // [RH] who is this?
|
||||
|
||||
const PClass *cls; // class of associated PlayerPawn
|
||||
PClassPlayerPawn *cls; // class of associated PlayerPawn
|
||||
|
||||
float DesiredFOV; // desired field of vision
|
||||
float FOV; // current field of vision
|
||||
|
@ -434,9 +455,9 @@ public:
|
|||
short fixedlightlevel;
|
||||
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
|
||||
int morphTics; // player is a chicken/pig if > 0
|
||||
const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
PClassPlayerPawn *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
int MorphStyle; // which effects to apply for this player instance when morphed
|
||||
const PClass *MorphExitFlash; // flash to apply when demorphing (cache of value given to P_MorphPlayer)
|
||||
PClassActor *MorphExitFlash; // flash to apply when demorphing (cache of value given to P_MorphPlayer)
|
||||
TObjPtr<AWeapon> PremorphWeapon; // ready weapon before morphing
|
||||
int chickenPeck; // chicken peck countdown
|
||||
int jumpTics; // delay the next jump for a moment
|
||||
|
|
|
@ -158,7 +158,7 @@ enum EDemoCommand
|
|||
DEM_CONVREPLY, // 59 Word: Dialogue node, Byte: Reply number
|
||||
DEM_CONVCLOSE, // 60
|
||||
DEM_CONVNULL, // 61
|
||||
DEM_RUNSPECIAL, // 62 Byte: Special number, Byte: Arg count, Ints: Args
|
||||
DEM_RUNSPECIAL, // 62 Word: Special number, Byte: Arg count, Ints: Args
|
||||
DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees)
|
||||
DEM_ADVANCEINTER, // 64 Advance intermission screen state
|
||||
DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int
|
||||
|
|
|
@ -364,9 +364,9 @@ void FDecalLib::ReadAllDecals ()
|
|||
ReadDecals (sc);
|
||||
}
|
||||
// Supporting code to allow specifying decals directly in the DECORATE lump
|
||||
for (i = 0; i < PClass::m_RuntimeActors.Size(); i++)
|
||||
for (i = 0; i < PClassActor::AllActorClasses.Size(); i++)
|
||||
{
|
||||
AActor *def = (AActor*)GetDefaultByType (PClass::m_RuntimeActors[i]);
|
||||
AActor *def = (AActor*)GetDefaultByType (PClassActor::AllActorClasses[i]);
|
||||
|
||||
FName v = ENamedName(intptr_t(def->DecalGenerator));
|
||||
if (v.IsValidName())
|
||||
|
@ -601,7 +601,7 @@ void FDecalLib::ParseDecalGroup (FScanner &sc)
|
|||
|
||||
void FDecalLib::ParseGenerator (FScanner &sc)
|
||||
{
|
||||
const PClass *type;
|
||||
PClassActor *type;
|
||||
FDecalBase *decal;
|
||||
bool optional = false;
|
||||
|
||||
|
@ -610,8 +610,8 @@ void FDecalLib::ParseGenerator (FScanner &sc)
|
|||
optional = sc.Compare("optional");
|
||||
if (optional) sc.MustGetString();
|
||||
|
||||
type = PClass::FindClass (sc.String);
|
||||
if (type == NULL || type->ActorInfo == NULL)
|
||||
type = PClass::FindActor (sc.String);
|
||||
if (type == NULL)
|
||||
{
|
||||
if (!optional) sc.ScriptError ("%s is not an actor.", sc.String);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
class FScanner;
|
||||
class FDecalTemplate;
|
||||
struct FDecalAnimator;
|
||||
struct PClass;
|
||||
class PClass;
|
||||
class DBaseDecal;
|
||||
struct side_t;
|
||||
|
||||
|
|
241
src/dobject.cpp
241
src/dobject.cpp
|
@ -49,146 +49,18 @@
|
|||
#include "dsectoreffect.h"
|
||||
#include "farchive.h"
|
||||
|
||||
PClass DObject::_StaticType;
|
||||
ClassReg DObject::RegistrationInfo =
|
||||
{
|
||||
&DObject::_StaticType, // MyClass
|
||||
NULL, // MyClass
|
||||
"DObject", // Name
|
||||
NULL, // ParentType
|
||||
sizeof(DObject), // SizeOf
|
||||
NULL, // Pointers
|
||||
&DObject::InPlaceConstructor // ConstructNative
|
||||
&DObject::InPlaceConstructor, // ConstructNative
|
||||
sizeof(DObject), // SizeOf
|
||||
CLASSREG_PClass, // MetaClassNum
|
||||
};
|
||||
_DECLARE_TI(DObject)
|
||||
|
||||
FMetaTable::~FMetaTable ()
|
||||
{
|
||||
FreeMeta ();
|
||||
}
|
||||
|
||||
FMetaTable::FMetaTable (const FMetaTable &other)
|
||||
{
|
||||
Meta = NULL;
|
||||
CopyMeta (&other);
|
||||
}
|
||||
|
||||
FMetaTable &FMetaTable::operator = (const FMetaTable &other)
|
||||
{
|
||||
CopyMeta (&other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FMetaTable::FreeMeta ()
|
||||
{
|
||||
while (Meta != NULL)
|
||||
{
|
||||
FMetaData *meta = Meta;
|
||||
|
||||
switch (meta->Type)
|
||||
{
|
||||
case META_String:
|
||||
delete[] meta->Value.String;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Meta = meta->Next;
|
||||
delete meta;
|
||||
}
|
||||
}
|
||||
|
||||
void FMetaTable::CopyMeta (const FMetaTable *other)
|
||||
{
|
||||
const FMetaData *meta_src;
|
||||
FMetaData **meta_dest;
|
||||
|
||||
FreeMeta ();
|
||||
|
||||
meta_src = other->Meta;
|
||||
meta_dest = &Meta;
|
||||
while (meta_src != NULL)
|
||||
{
|
||||
FMetaData *newmeta = new FMetaData (meta_src->Type, meta_src->ID);
|
||||
switch (meta_src->Type)
|
||||
{
|
||||
case META_String:
|
||||
newmeta->Value.String = copystring (meta_src->Value.String);
|
||||
break;
|
||||
default:
|
||||
newmeta->Value = meta_src->Value;
|
||||
break;
|
||||
}
|
||||
*meta_dest = newmeta;
|
||||
meta_dest = &newmeta->Next;
|
||||
meta_src = meta_src->Next;
|
||||
}
|
||||
*meta_dest = NULL;
|
||||
}
|
||||
|
||||
FMetaData *FMetaTable::FindMeta (EMetaType type, DWORD id) const
|
||||
{
|
||||
FMetaData *meta = Meta;
|
||||
|
||||
while (meta != NULL)
|
||||
{
|
||||
if (meta->ID == id && meta->Type == type)
|
||||
{
|
||||
return meta;
|
||||
}
|
||||
meta = meta->Next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FMetaData *FMetaTable::FindMetaDef (EMetaType type, DWORD id)
|
||||
{
|
||||
FMetaData *meta = FindMeta (type, id);
|
||||
if (meta == NULL)
|
||||
{
|
||||
meta = new FMetaData (type, id);
|
||||
meta->Next = Meta;
|
||||
meta->Value.String = NULL;
|
||||
Meta = meta;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
void FMetaTable::SetMetaInt (DWORD id, int parm)
|
||||
{
|
||||
FMetaData *meta = FindMetaDef (META_Int, id);
|
||||
meta->Value.Int = parm;
|
||||
}
|
||||
|
||||
int FMetaTable::GetMetaInt (DWORD id, int def) const
|
||||
{
|
||||
FMetaData *meta = FindMeta (META_Int, id);
|
||||
return meta != NULL ? meta->Value.Int : def;
|
||||
}
|
||||
|
||||
void FMetaTable::SetMetaFixed (DWORD id, fixed_t parm)
|
||||
{
|
||||
FMetaData *meta = FindMetaDef (META_Fixed, id);
|
||||
meta->Value.Fixed = parm;
|
||||
}
|
||||
|
||||
fixed_t FMetaTable::GetMetaFixed (DWORD id, fixed_t def) const
|
||||
{
|
||||
FMetaData *meta = FindMeta (META_Fixed, id);
|
||||
return meta != NULL ? meta->Value.Fixed : def;
|
||||
}
|
||||
|
||||
void FMetaTable::SetMetaString (DWORD id, const char *parm)
|
||||
{
|
||||
FMetaData *meta = FindMetaDef (META_String, id);
|
||||
ReplaceString (&meta->Value.String, parm);
|
||||
}
|
||||
|
||||
const char *FMetaTable::GetMetaString (DWORD id) const
|
||||
{
|
||||
FMetaData *meta = FindMeta (META_String, id);
|
||||
return meta != NULL ? meta->Value.String : NULL;
|
||||
}
|
||||
|
||||
CCMD (dumpactors)
|
||||
{
|
||||
const char *const filters[32] =
|
||||
|
@ -200,19 +72,26 @@ CCMD (dumpactors)
|
|||
"25:DoomStrifeChex", "26:HereticStrifeChex", "27:NotHexen", "28:HexenStrifeChex", "29:NotHeretic",
|
||||
"30:NotDoom", "31:All",
|
||||
};
|
||||
Printf("%i object class types total\nActor\tEd Num\tSpawnID\tFilter\tSource\n", PClass::m_Types.Size());
|
||||
for (unsigned int i = 0; i < PClass::m_Types.Size(); i++)
|
||||
Printf("%i object class types total\nActor\tEd Num\tSpawnID\tFilter\tSource\n", PClass::AllClasses.Size());
|
||||
for (unsigned int i = 0; i < PClass::AllClasses.Size(); i++)
|
||||
{
|
||||
PClass *cls = PClass::m_Types[i];
|
||||
if (cls != NULL && cls->ActorInfo != NULL)
|
||||
PClass *cls = PClass::AllClasses[i];
|
||||
PClassActor *acls = dyn_cast<PClassActor>(cls);
|
||||
if (acls != NULL)
|
||||
{
|
||||
Printf("%s\t%i\t%i\t%s\t%s\n",
|
||||
cls->TypeName.GetChars(), cls->ActorInfo->DoomEdNum,
|
||||
cls->ActorInfo->SpawnID, filters[cls->ActorInfo->GameFilter & 31],
|
||||
cls->Meta.GetMetaString (ACMETA_Lump));
|
||||
acls->TypeName.GetChars(), acls->DoomEdNum,
|
||||
acls->SpawnID, filters[acls->GameFilter & 31],
|
||||
acls->SourceLumpName.GetChars());
|
||||
}
|
||||
else if (cls != NULL)
|
||||
{
|
||||
Printf("%s\tn/a\tn/a\tn/a\tEngine (not an actor type)\n", cls->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Type %i is not an object class\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,7 +202,6 @@ CCMD (dumpclasses)
|
|||
int shown, omitted;
|
||||
DumpInfo *tree = NULL;
|
||||
const PClass *root = NULL;
|
||||
bool showall = true;
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
|
@ -333,24 +211,14 @@ CCMD (dumpclasses)
|
|||
Printf ("Class '%s' not found\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (stricmp (argv[1], "Actor") == 0)
|
||||
{
|
||||
if (argv.argc() < 3 || stricmp (argv[2], "all") != 0)
|
||||
{
|
||||
showall = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shown = omitted = 0;
|
||||
DumpInfo::AddType (&tree, root != NULL ? root : RUNTIME_CLASS(DObject));
|
||||
for (i = 0; i < PClass::m_Types.Size(); i++)
|
||||
for (i = 0; i < PClass::AllClasses.Size(); i++)
|
||||
{
|
||||
PClass *cls = PClass::m_Types[i];
|
||||
if (root == NULL ||
|
||||
(cls->IsDescendantOf (root) &&
|
||||
(showall || cls == root ||
|
||||
cls->ActorInfo != root->ActorInfo)))
|
||||
PClass *cls = PClass::AllClasses[i];
|
||||
if (root == NULL || cls == root || cls->IsDescendantOf(root))
|
||||
{
|
||||
DumpInfo::AddType (&tree, cls);
|
||||
// Printf (" %s\n", PClass::m_Types[i]->Name + 1);
|
||||
|
@ -389,7 +257,7 @@ DObject::DObject (PClass *inClass)
|
|||
|
||||
DObject::~DObject ()
|
||||
{
|
||||
if (!(ObjectFlags & OF_Cleanup))
|
||||
if (!(ObjectFlags & OF_Cleanup) && !PClass::bShutdown)
|
||||
{
|
||||
DObject **probe;
|
||||
PClass *type = GetClass();
|
||||
|
@ -487,9 +355,12 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
|
|||
int i;
|
||||
|
||||
// Go through all objects.
|
||||
i = 0;DObject *last=0;
|
||||
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
|
||||
{
|
||||
i++;
|
||||
changed += probe->PointerSubstitution(old, notOld);
|
||||
last = probe;
|
||||
}
|
||||
|
||||
// Go through the bodyque.
|
||||
|
@ -549,23 +420,33 @@ void DObject::SerializeUserVars(FArchive &arc)
|
|||
// Write all user variables.
|
||||
for (; symt != NULL; symt = symt->ParentSymbolTable)
|
||||
{
|
||||
for (unsigned i = 0; i < symt->Symbols.Size(); ++i)
|
||||
{
|
||||
PSymbol *sym = symt->Symbols[i];
|
||||
if (sym->SymbolType == SYM_Variable)
|
||||
{
|
||||
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
|
||||
if (var->bUserVar)
|
||||
{
|
||||
count = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
|
||||
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
|
||||
PSymbolTable::MapType::Iterator it(symt->Symbols);
|
||||
PSymbolTable::MapType::Pair *pair;
|
||||
|
||||
arc << var->SymbolName;
|
||||
arc.WriteCount(count);
|
||||
for (j = 0; j < count; ++j)
|
||||
{
|
||||
arc << varloc[j];
|
||||
}
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
PField *var = dyn_cast<PField>(pair->Value);
|
||||
if (var != NULL && !(var->Flags & VARF_Native))
|
||||
{
|
||||
PType *type = var->Type;
|
||||
PArray *arraytype = dyn_cast<PArray>(type);
|
||||
if (arraytype == NULL)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = arraytype->ElementCount;
|
||||
type = arraytype->ElementType;
|
||||
}
|
||||
assert(type == TypeSInt32);
|
||||
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->Offset);
|
||||
|
||||
arc << var->SymbolName;
|
||||
arc.WriteCount(count);
|
||||
for (j = 0; j < count; ++j)
|
||||
{
|
||||
arc << varloc[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -580,18 +461,24 @@ void DObject::SerializeUserVars(FArchive &arc)
|
|||
arc << varname;
|
||||
while (varname != NAME_None)
|
||||
{
|
||||
PSymbol *sym = symt->FindSymbol(varname, true);
|
||||
PField *var = dyn_cast<PField>(symt->FindSymbol(varname, true));
|
||||
DWORD wanted = 0;
|
||||
|
||||
if (sym != NULL && sym->SymbolType == SYM_Variable)
|
||||
if (var != NULL && !(var->Flags & VARF_Native))
|
||||
{
|
||||
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
|
||||
|
||||
if (var->bUserVar)
|
||||
PType *type = var->Type;
|
||||
PArray *arraytype = dyn_cast<PArray>(type);
|
||||
if (arraytype != NULL)
|
||||
{
|
||||
wanted = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
|
||||
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
|
||||
wanted = arraytype->ElementCount;
|
||||
type = arraytype->ElementType;
|
||||
}
|
||||
else
|
||||
{
|
||||
wanted = 1;
|
||||
}
|
||||
assert(type == TypeSInt32);
|
||||
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->Offset);
|
||||
}
|
||||
count = arc.ReadCount();
|
||||
for (j = 0; j < MIN(wanted, count); ++j)
|
||||
|
|
160
src/dobject.h
160
src/dobject.h
|
@ -37,7 +37,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "doomtype.h"
|
||||
|
||||
struct PClass;
|
||||
class PClass;
|
||||
|
||||
class FArchive;
|
||||
|
||||
|
@ -78,89 +78,68 @@ class DFloorWaggle;
|
|||
class DPlat;
|
||||
class DPillar;
|
||||
|
||||
struct FActorInfo;
|
||||
class PClassActor;
|
||||
|
||||
enum EMetaType
|
||||
#define RUNTIME_CLASS_CASTLESS(cls) (cls::RegistrationInfo.MyClass) // Passed a native class name, returns a PClass representing that class
|
||||
#define RUNTIME_CLASS(cls) ((cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // Like above, but returns the true type of the meta object
|
||||
#define RUNTIME_TEMPLATE_CLASS(cls) ((typename cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // RUNTIME_CLASS, but works with templated parameters on GCC
|
||||
#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object
|
||||
|
||||
// Enumerations for the meta classes created by ClassReg::RegisterClass()
|
||||
enum
|
||||
{
|
||||
META_Int, // An int
|
||||
META_Fixed, // A fixed point number
|
||||
META_String, // A string
|
||||
CLASSREG_PClass,
|
||||
CLASSREG_PClassActor,
|
||||
CLASSREG_PClassInventory,
|
||||
CLASSREG_PClassAmmo,
|
||||
CLASSREG_PClassHealth,
|
||||
CLASSREG_PClassPuzzleItem,
|
||||
CLASSREG_PClassWeapon,
|
||||
CLASSREG_PClassPlayerPawn,
|
||||
CLASSREG_PClassType,
|
||||
CLASSREG_PClassClass,
|
||||
};
|
||||
|
||||
class FMetaData
|
||||
{
|
||||
private:
|
||||
FMetaData (EMetaType type, uint32 id) : Type(type), ID(id) {}
|
||||
|
||||
FMetaData *Next;
|
||||
EMetaType Type;
|
||||
uint32 ID;
|
||||
union
|
||||
{
|
||||
int Int;
|
||||
char *String;
|
||||
fixed_t Fixed;
|
||||
} Value;
|
||||
|
||||
friend class FMetaTable;
|
||||
};
|
||||
|
||||
class FMetaTable
|
||||
{
|
||||
public:
|
||||
FMetaTable() : Meta(NULL) {}
|
||||
FMetaTable(const FMetaTable &other);
|
||||
~FMetaTable();
|
||||
FMetaTable &operator = (const FMetaTable &other);
|
||||
|
||||
void SetMetaInt (uint32 id, int parm);
|
||||
void SetMetaFixed (uint32 id, fixed_t parm);
|
||||
void SetMetaString (uint32 id, const char *parm); // The string is copied
|
||||
|
||||
int GetMetaInt (uint32 id, int def=0) const;
|
||||
fixed_t GetMetaFixed (uint32 id, fixed_t def=0) const;
|
||||
const char *GetMetaString (uint32 id) const;
|
||||
|
||||
FMetaData *FindMeta (EMetaType type, uint32 id) const;
|
||||
|
||||
private:
|
||||
FMetaData *Meta;
|
||||
FMetaData *FindMetaDef (EMetaType type, uint32 id);
|
||||
void FreeMeta ();
|
||||
void CopyMeta (const FMetaTable *other);
|
||||
};
|
||||
|
||||
#define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object
|
||||
#define RUNTIME_CLASS(cls) (&cls::_StaticType) // Passed a class name, returns a PClass representing that class
|
||||
#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object
|
||||
|
||||
struct ClassReg
|
||||
{
|
||||
PClass *MyClass;
|
||||
const char *Name;
|
||||
PClass *ParentType;
|
||||
unsigned int SizeOf;
|
||||
ClassReg *ParentType;
|
||||
const size_t *Pointers;
|
||||
void (*ConstructNative)(void *);
|
||||
unsigned int SizeOf:28;
|
||||
unsigned int MetaClassNum:4;
|
||||
|
||||
void RegisterClass() const;
|
||||
PClass *RegisterClass();
|
||||
void SetupClass(PClass *cls);
|
||||
};
|
||||
|
||||
enum EInPlace { EC_InPlace };
|
||||
|
||||
#define DECLARE_ABSTRACT_CLASS(cls,parent) \
|
||||
public: \
|
||||
static PClass _StaticType; \
|
||||
virtual PClass *StaticType() const { return &_StaticType; } \
|
||||
static ClassReg RegistrationInfo, *RegistrationInfoPtr; \
|
||||
virtual PClass *StaticType() const; \
|
||||
static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \
|
||||
private: \
|
||||
typedef parent Super; \
|
||||
typedef cls ThisClass;
|
||||
|
||||
#define DECLARE_ABSTRACT_CLASS_WITH_META(cls,parent,meta) \
|
||||
DECLARE_ABSTRACT_CLASS(cls,parent) \
|
||||
public: \
|
||||
typedef meta MetaClass; \
|
||||
MetaClass *GetClass() const { return static_cast<MetaClass *>(DObject::GetClass()); } \
|
||||
protected: \
|
||||
enum { MetaClassNum = CLASSREG_##meta }; private: \
|
||||
|
||||
#define DECLARE_CLASS(cls,parent) \
|
||||
DECLARE_ABSTRACT_CLASS(cls,parent) \
|
||||
private: static void InPlaceConstructor (void *mem);
|
||||
|
||||
#define DECLARE_CLASS_WITH_META(cls,parent,meta) \
|
||||
DECLARE_ABSTRACT_CLASS_WITH_META(cls,parent,meta) \
|
||||
private: static void InPlaceConstructor (void *mem);
|
||||
|
||||
#define HAS_OBJECT_POINTERS \
|
||||
static const size_t PointerOffsets[];
|
||||
|
||||
|
@ -170,23 +149,23 @@ private: \
|
|||
#define END_POINTERS ~(size_t)0 };
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma data_seg(".creg$u")
|
||||
# pragma data_seg()
|
||||
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg *cls::RegistrationInfoPtr = &cls::RegistrationInfo;
|
||||
# pragma section(".creg$u",read)
|
||||
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg * const cls::RegistrationInfoPtr = &cls::RegistrationInfo;
|
||||
#else
|
||||
# define _DECLARE_TI(cls) ClassReg *cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
|
||||
# define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
|
||||
#endif
|
||||
|
||||
#define _IMP_PCLASS(cls,ptrs,create) \
|
||||
PClass cls::_StaticType; \
|
||||
ClassReg cls::RegistrationInfo = {\
|
||||
RUNTIME_CLASS(cls), \
|
||||
NULL, \
|
||||
#cls, \
|
||||
RUNTIME_CLASS(cls::Super), \
|
||||
sizeof(cls), \
|
||||
&cls::Super::RegistrationInfo, \
|
||||
ptrs, \
|
||||
create }; \
|
||||
_DECLARE_TI(cls)
|
||||
create, \
|
||||
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; }
|
||||
|
@ -207,7 +186,6 @@ private: \
|
|||
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
|
||||
const size_t cls::PointerOffsets[] = {
|
||||
|
||||
|
||||
enum EObjectFlags
|
||||
{
|
||||
// GC flags
|
||||
|
@ -227,6 +205,7 @@ 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_StateChanged = 1 << 11, // Used by A_Jump* functions to feed back to SetState()
|
||||
};
|
||||
|
||||
template<class T> class TObjPtr;
|
||||
|
@ -268,6 +247,9 @@ namespace GC
|
|||
// Size of GC steps.
|
||||
extern int StepMul;
|
||||
|
||||
// Is this the final collection just before exit?
|
||||
extern bool FinalGC;
|
||||
|
||||
// Current white value for known-dead objects.
|
||||
static inline uint32 OtherWhite()
|
||||
{
|
||||
|
@ -319,6 +301,9 @@ namespace GC
|
|||
// is NULLed instead.
|
||||
void Mark(DObject **obj);
|
||||
|
||||
// Marks an array of objects.
|
||||
void MarkArray(DObject **objs, size_t count);
|
||||
|
||||
// For cleanup
|
||||
void DelSoftRootHead();
|
||||
|
||||
|
@ -340,6 +325,15 @@ namespace GC
|
|||
obj = t;
|
||||
}
|
||||
template<class T> void Mark(TObjPtr<T> &obj);
|
||||
|
||||
template<class T> void MarkArray(T **obj, size_t count)
|
||||
{
|
||||
MarkArray((DObject **)(obj), count);
|
||||
}
|
||||
template<class T> void MarkArray(TArray<T> &arr)
|
||||
{
|
||||
MarkArray(&arr[0], arr.Size());
|
||||
}
|
||||
}
|
||||
|
||||
// A template class to help with handling read barriers. It does not
|
||||
|
@ -441,12 +435,14 @@ template<class T> inline void GC::Mark(TObjPtr<T> &obj)
|
|||
class DObject
|
||||
{
|
||||
public:
|
||||
static PClass _StaticType;
|
||||
virtual PClass *StaticType() const { return &_StaticType; }
|
||||
static ClassReg RegistrationInfo, *RegistrationInfoPtr;
|
||||
virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
|
||||
static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
|
||||
static void InPlaceConstructor (void *mem);
|
||||
typedef PClass MetaClass;
|
||||
private:
|
||||
typedef DObject ThisClass;
|
||||
protected:
|
||||
enum { MetaClassNum = CLASSREG_PClass };
|
||||
|
||||
// Per-instance variables. There are four.
|
||||
private:
|
||||
|
@ -466,6 +462,10 @@ public:
|
|||
|
||||
void SerializeUserVars(FArchive &arc);
|
||||
virtual void Serialize (FArchive &arc);
|
||||
void ClearClass()
|
||||
{
|
||||
Class = NULL;
|
||||
}
|
||||
|
||||
// For catching Serialize functions in derived classes
|
||||
// that don't call their base class.
|
||||
|
@ -601,4 +601,18 @@ inline bool DObject::IsA (const PClass *type) const
|
|||
return (type == GetClass());
|
||||
}
|
||||
|
||||
template<class T> T *dyn_cast(DObject *p)
|
||||
{
|
||||
if (p != NULL && p->IsKindOf(RUNTIME_CLASS_CASTLESS(T)))
|
||||
{
|
||||
return static_cast<T *>(p);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template<class T> const T *dyn_cast(const DObject *p)
|
||||
{
|
||||
return dyn_cast<T>(const_cast<DObject *>(p));
|
||||
}
|
||||
|
||||
#endif //__DOBJECT_H__
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "m_argv.h"
|
||||
#include "po_man.h"
|
||||
#include "autosegs.h"
|
||||
#include "v_video.h"
|
||||
#include "menu/menu.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
@ -150,6 +151,7 @@ int Pause = DEFAULT_GCPAUSE;
|
|||
int StepMul = DEFAULT_GCMUL;
|
||||
int StepCount;
|
||||
size_t Dept;
|
||||
bool FinalGC;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -286,6 +288,22 @@ void Mark(DObject **obj)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// MarkArray
|
||||
//
|
||||
// Mark an array of objects gray.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void MarkArray(DObject **obj, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
Mark(obj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// MarkRoot
|
||||
|
@ -336,6 +354,25 @@ static void MarkRoot()
|
|||
}
|
||||
Mark(SectorMarker);
|
||||
Mark(interpolator.Head);
|
||||
// Mark action functions
|
||||
if (!FinalGC)
|
||||
{
|
||||
FAutoSegIterator probe(ARegHead, ARegTail);
|
||||
|
||||
while (*++probe != NULL)
|
||||
{
|
||||
AFuncDesc *afunc = (AFuncDesc *)*probe;
|
||||
Mark(*(afunc->VMPointer));
|
||||
}
|
||||
}
|
||||
// Mark types
|
||||
TypeTable.Mark();
|
||||
for (unsigned int i = 0; i < PClass::AllClasses.Size(); ++i)
|
||||
{
|
||||
Mark(PClass::AllClasses[i]);
|
||||
}
|
||||
// Mark global symbols
|
||||
GlobalSymbols.MarkSymbols();
|
||||
// Mark bot stuff.
|
||||
Mark(bglobal.firstthing);
|
||||
Mark(bglobal.body1);
|
||||
|
@ -365,7 +402,7 @@ static void MarkRoot()
|
|||
//
|
||||
// Atomic
|
||||
//
|
||||
// If their were any propagations that needed to be done atomicly, they
|
||||
// If there were any propagations that needed to be done atomicly, they
|
||||
// would go here. It also sets things up for the sweep state.
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
2761
src/dobjtype.cpp
2761
src/dobjtype.cpp
File diff suppressed because it is too large
Load diff
813
src/dobjtype.h
813
src/dobjtype.h
|
@ -6,95 +6,78 @@
|
|||
#endif
|
||||
|
||||
#include "thingdef/thingdef_type.h"
|
||||
#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
|
||||
|
||||
// Symbol information -------------------------------------------------------
|
||||
|
||||
enum ESymbolType
|
||||
{
|
||||
SYM_Const,
|
||||
SYM_Variable,
|
||||
SYM_ActionFunction
|
||||
};
|
||||
|
||||
struct PSymbol
|
||||
class PSymbol : public DObject
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PSymbol, DObject);
|
||||
public:
|
||||
virtual ~PSymbol();
|
||||
|
||||
ESymbolType SymbolType;
|
||||
FName SymbolName;
|
||||
|
||||
protected:
|
||||
PSymbol(FName name, ESymbolType type) { SymbolType = type; SymbolName = name; }
|
||||
};
|
||||
|
||||
// A constant value ---------------------------------------------------------
|
||||
|
||||
struct PSymbolConst : public PSymbol
|
||||
{
|
||||
int ValueType;
|
||||
union
|
||||
{
|
||||
int Value;
|
||||
double Float;
|
||||
};
|
||||
|
||||
PSymbolConst(FName name) : PSymbol(name, SYM_Const) {}
|
||||
};
|
||||
|
||||
// A variable ---------------------------------------------------------
|
||||
|
||||
struct PSymbolVariable : public PSymbol
|
||||
{
|
||||
FExpressionType ValueType;
|
||||
//int size;
|
||||
intptr_t offset;
|
||||
bool bUserVar;
|
||||
|
||||
PSymbolVariable(FName name) : PSymbol(name, SYM_Variable) {}
|
||||
PSymbol(FName name) { SymbolName = name; }
|
||||
};
|
||||
|
||||
// An action function -------------------------------------------------------
|
||||
//
|
||||
// The Arguments string is a string of characters as understood by
|
||||
// the DECORATE parser:
|
||||
//
|
||||
// If the letter is uppercase, it is required. Lowercase letters are optional.
|
||||
// i = integer
|
||||
// f = fixed point
|
||||
// s = sound name
|
||||
// m = actor name
|
||||
// t = string
|
||||
// l = jump label
|
||||
// c = color
|
||||
// x = expression
|
||||
// y = expression
|
||||
// If the final character is a +, the previous parameter is repeated indefinitely,
|
||||
// and an "imaginary" first parameter is inserted containing the total number of
|
||||
// parameters passed.
|
||||
|
||||
struct FState;
|
||||
struct StateCallData;
|
||||
typedef void (*actionf_p)(AActor *self, AActor *stateowner, FState *state, int parameters, StateCallData *statecall);
|
||||
class VMFrameStack;
|
||||
struct VMValue;
|
||||
struct VMReturn;
|
||||
typedef int (*actionf_p)(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/
|
||||
class VMFunction;
|
||||
|
||||
struct PSymbolActionFunction : public PSymbol
|
||||
// A VM function ------------------------------------------------------------
|
||||
|
||||
class PSymbolVMFunction : public PSymbol
|
||||
{
|
||||
FString Arguments;
|
||||
actionf_p Function;
|
||||
int defaultparameterindex;
|
||||
DECLARE_CLASS(PSymbolVMFunction, PSymbol);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
VMFunction *Function;
|
||||
|
||||
PSymbolActionFunction(FName name) : PSymbol(name, SYM_ActionFunction) {}
|
||||
PSymbolVMFunction(FName name) : PSymbol(name) {}
|
||||
PSymbolVMFunction() : PSymbol(NAME_None) {}
|
||||
};
|
||||
|
||||
// A symbol for a type ------------------------------------------------------
|
||||
|
||||
class PSymbolType : public PSymbol
|
||||
{
|
||||
DECLARE_CLASS(PSymbolType, PSymbol);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
class PType *Type;
|
||||
|
||||
PSymbolType(FName name, class PType *ty) : PSymbol(name), Type(ty) {}
|
||||
PSymbolType() : PSymbol(NAME_None) {}
|
||||
};
|
||||
|
||||
// A symbol table -----------------------------------------------------------
|
||||
|
||||
class PSymbolTable
|
||||
struct PSymbolTable
|
||||
{
|
||||
public:
|
||||
PSymbolTable() : ParentSymbolTable(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
PSymbolTable();
|
||||
PSymbolTable(PSymbolTable *parent);
|
||||
~PSymbolTable();
|
||||
|
||||
size_t MarkSymbols();
|
||||
|
||||
// Sets the table to use for searches if this one doesn't contain the
|
||||
// requested symbol.
|
||||
void SetParentTable (PSymbolTable *parent);
|
||||
|
@ -112,49 +95,549 @@ public:
|
|||
void ReleaseSymbols();
|
||||
|
||||
private:
|
||||
typedef TMap<FName, PSymbol *> MapType;
|
||||
|
||||
PSymbolTable *ParentSymbolTable;
|
||||
TArray<PSymbol *> Symbols;
|
||||
MapType Symbols;
|
||||
|
||||
friend class DObject;
|
||||
};
|
||||
|
||||
extern PSymbolTable GlobalSymbols;
|
||||
|
||||
// Basic information shared by all types ------------------------------------
|
||||
|
||||
// Only one copy of a type is ever instantiated at one time.
|
||||
// - Enums, classes, and structs are defined by their names and outer classes.
|
||||
// - Pointers are uniquely defined by the type they point at.
|
||||
// - ClassPointers are also defined by their class restriction.
|
||||
// - Arrays are defined by their element type and count.
|
||||
// - DynArrays are defined by their element type.
|
||||
// - Maps are defined by their key and value types.
|
||||
// - Prototypes are defined by the argument and return types.
|
||||
// - Functions are defined by their names and outer objects.
|
||||
// In table form:
|
||||
// Outer Name Type Type2 Count
|
||||
// Enum * *
|
||||
// Class * *
|
||||
// Struct * *
|
||||
// Function * *
|
||||
// Pointer *
|
||||
// ClassPointer + *
|
||||
// Array * *
|
||||
// DynArray *
|
||||
// Map * *
|
||||
// Prototype *+ *+
|
||||
|
||||
struct ZCC_ExprConstant;
|
||||
class PClassType;
|
||||
class PType : public DObject
|
||||
{
|
||||
//DECLARE_ABSTRACT_CLASS_WITH_META(PType, DObject, PClassType);
|
||||
// We need to unravel the _WITH_META macro, since PClassType isn't defined yet,
|
||||
// and we can't define it until we've defined PClass. But we can't define that
|
||||
// without defining PType.
|
||||
DECLARE_ABSTRACT_CLASS(PType, DObject)
|
||||
HAS_OBJECT_POINTERS;
|
||||
protected:
|
||||
enum { MetaClassNum = CLASSREG_PClassType };
|
||||
public:
|
||||
typedef PClassType MetaClass;
|
||||
MetaClass *GetClass() const;
|
||||
|
||||
struct Conversion
|
||||
{
|
||||
Conversion(PType *target, void (*convert)(ZCC_ExprConstant *, class FSharedStringArena &))
|
||||
: TargetType(target), ConvertConstant(convert) {}
|
||||
|
||||
PType *TargetType;
|
||||
void (*ConvertConstant)(ZCC_ExprConstant *val, class FSharedStringArena &strdump);
|
||||
};
|
||||
|
||||
unsigned int Size; // this type's size
|
||||
unsigned int Align; // this type's preferred alignment
|
||||
PType *HashNext; // next type in this type table
|
||||
PSymbolTable Symbols;
|
||||
|
||||
PType();
|
||||
PType(unsigned int size, unsigned int align);
|
||||
virtual ~PType();
|
||||
|
||||
bool AddConversion(PType *target, void (*convertconst)(ZCC_ExprConstant *, class FSharedStringArena &));
|
||||
|
||||
int FindConversion(PType *target, const Conversion **slots, int numslots);
|
||||
|
||||
// Sets the value of a variable of this type at (addr)
|
||||
virtual void SetValue(void *addr, int val);
|
||||
|
||||
// Gets the value of a variable of this type at (addr)
|
||||
virtual int GetValueInt(void *addr) const;
|
||||
|
||||
// Gets the opcode to store from a register to memory
|
||||
virtual int GetStoreOp() const;
|
||||
|
||||
// Gets the opcode to load from memory to a register
|
||||
virtual int GetLoadOp() const;
|
||||
|
||||
// Gets the register type for this type
|
||||
virtual int GetRegType() const;
|
||||
|
||||
// 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.
|
||||
// It is up to the caller to make sure they are the correct types. There is
|
||||
// only one prototype for this function in order to simplify type table
|
||||
// management.
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
|
||||
// Get the type IDs used by IsMatch
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
|
||||
size_t PropagateMark();
|
||||
|
||||
static void StaticInit();
|
||||
|
||||
private:
|
||||
// Stuff for type conversion searches
|
||||
class VisitQueue
|
||||
{
|
||||
public:
|
||||
VisitQueue() : In(0), Out(0) {}
|
||||
void Push(PType *type);
|
||||
PType *Pop();
|
||||
bool IsEmpty() { return In == Out; }
|
||||
|
||||
private:
|
||||
// This is a fixed-sized ring buffer.
|
||||
PType *Queue[64];
|
||||
int In, Out;
|
||||
|
||||
void Advance(int &ptr)
|
||||
{
|
||||
ptr = (ptr + 1) & (countof(Queue) - 1);
|
||||
}
|
||||
};
|
||||
|
||||
class VisitedNodeSet
|
||||
{
|
||||
public:
|
||||
VisitedNodeSet() { memset(Buckets, 0, sizeof(Buckets)); }
|
||||
void Insert(PType *node);
|
||||
bool Check(const PType *node);
|
||||
|
||||
private:
|
||||
PType *Buckets[32];
|
||||
|
||||
size_t Hash(const PType *type) { return size_t(type) >> 4; }
|
||||
};
|
||||
|
||||
TArray<Conversion> Conversions;
|
||||
PType *PredType;
|
||||
PType *VisitNext;
|
||||
short PredConv;
|
||||
short Distance;
|
||||
|
||||
void MarkPred(PType *pred, int conv, int dist)
|
||||
{
|
||||
PredType = pred;
|
||||
PredConv = conv;
|
||||
Distance = dist;
|
||||
}
|
||||
void FillConversionPath(const Conversion **slots);
|
||||
};
|
||||
|
||||
// Not-really-a-type types --------------------------------------------------
|
||||
|
||||
class PErrorType : public PType
|
||||
{
|
||||
DECLARE_CLASS(PErrorType, PType);
|
||||
public:
|
||||
PErrorType() : PType(0, 1) {}
|
||||
};
|
||||
|
||||
class PVoidType : public PType
|
||||
{
|
||||
DECLARE_CLASS(PVoidType, PType);
|
||||
public:
|
||||
PVoidType() : PType(0, 1) {}
|
||||
};
|
||||
|
||||
// Some categorization typing -----------------------------------------------
|
||||
|
||||
class PBasicType : public PType
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
|
||||
public:
|
||||
PBasicType();
|
||||
PBasicType(unsigned int size, unsigned int align);
|
||||
};
|
||||
|
||||
class PCompoundType : public PType
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
|
||||
};
|
||||
|
||||
class PNamedType : public PCompoundType
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PNamedType, PCompoundType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
DObject *Outer; // object this type is contained within
|
||||
FName TypeName; // this type's name
|
||||
|
||||
PNamedType() : Outer(NULL) {}
|
||||
PNamedType(FName name, DObject *outer) : Outer(outer), TypeName(name) {}
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
};
|
||||
|
||||
// Basic types --------------------------------------------------------------
|
||||
|
||||
class PInt : public PBasicType
|
||||
{
|
||||
DECLARE_CLASS(PInt, PBasicType);
|
||||
public:
|
||||
PInt(unsigned int size, bool unsign);
|
||||
|
||||
virtual void SetValue(void *addr, int val);
|
||||
virtual int GetValueInt(void *addr) const;
|
||||
virtual int GetStoreOp() const;
|
||||
virtual int GetLoadOp() const;
|
||||
virtual int GetRegType() const;
|
||||
|
||||
bool Unsigned;
|
||||
protected:
|
||||
PInt();
|
||||
};
|
||||
|
||||
class PBool : public PInt
|
||||
{
|
||||
DECLARE_CLASS(PBool, PInt);
|
||||
public:
|
||||
PBool();
|
||||
};
|
||||
|
||||
class PFloat : public PBasicType
|
||||
{
|
||||
DECLARE_CLASS(PFloat, PBasicType);
|
||||
public:
|
||||
PFloat(unsigned int size);
|
||||
|
||||
virtual void SetValue(void *addr, int val);
|
||||
virtual int GetValueInt(void *addr) const;
|
||||
virtual int GetStoreOp() const;
|
||||
virtual int GetLoadOp() const;
|
||||
virtual int GetRegType() const;
|
||||
protected:
|
||||
PFloat();
|
||||
private:
|
||||
struct SymbolInitF
|
||||
{
|
||||
ENamedName Name;
|
||||
double Value;
|
||||
};
|
||||
struct SymbolInitI
|
||||
{
|
||||
ENamedName Name;
|
||||
int Value;
|
||||
};
|
||||
|
||||
void SetSingleSymbols();
|
||||
void SetDoubleSymbols();
|
||||
void SetSymbols(const SymbolInitF *syminit, size_t count);
|
||||
void SetSymbols(const SymbolInitI *syminit, size_t count);
|
||||
};
|
||||
|
||||
class PString : public PBasicType
|
||||
{
|
||||
DECLARE_CLASS(PString, PBasicType);
|
||||
public:
|
||||
PString();
|
||||
|
||||
virtual int GetRegType() const;
|
||||
};
|
||||
|
||||
// Variations of integer types ----------------------------------------------
|
||||
|
||||
class PName : public PInt
|
||||
{
|
||||
DECLARE_CLASS(PName, PInt);
|
||||
public:
|
||||
PName();
|
||||
};
|
||||
|
||||
class PSound : public PInt
|
||||
{
|
||||
DECLARE_CLASS(PSound, PInt);
|
||||
public:
|
||||
PSound();
|
||||
};
|
||||
|
||||
class PColor : public PInt
|
||||
{
|
||||
DECLARE_CLASS(PColor, PInt);
|
||||
public:
|
||||
PColor();
|
||||
};
|
||||
|
||||
// Variations of floating point types ---------------------------------------
|
||||
// These get converted to floats when they're loaded from memory.
|
||||
|
||||
class PFixed : public PFloat
|
||||
{
|
||||
DECLARE_CLASS(PFixed, PFloat);
|
||||
public:
|
||||
PFixed();
|
||||
|
||||
virtual void SetValue(void *addr, int val);
|
||||
virtual int GetValueInt(void *addr) const;
|
||||
virtual int GetStoreOp() const;
|
||||
virtual int GetLoadOp() const;
|
||||
};
|
||||
|
||||
class PAngle : public PFloat
|
||||
{
|
||||
DECLARE_CLASS(PAngle, PFloat);
|
||||
public:
|
||||
PAngle();
|
||||
|
||||
virtual void SetValue(void *addr, int val);
|
||||
virtual int GetValueInt(void *addr) const;
|
||||
virtual int GetStoreOp() const;
|
||||
virtual int GetLoadOp() const;
|
||||
};
|
||||
|
||||
// Pointers -----------------------------------------------------------------
|
||||
|
||||
class PStatePointer : public PBasicType
|
||||
{
|
||||
DECLARE_CLASS(PStatePointer, PBasicType);
|
||||
public:
|
||||
PStatePointer();
|
||||
};
|
||||
|
||||
class PPointer : public PBasicType
|
||||
{
|
||||
DECLARE_CLASS(PPointer, PBasicType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PPointer(PType *pointsat);
|
||||
|
||||
PType *PointedType;
|
||||
|
||||
virtual int GetStoreOp() const;
|
||||
virtual int GetLoadOp() const;
|
||||
virtual int GetRegType() const;
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
protected:
|
||||
PPointer();
|
||||
};
|
||||
|
||||
class PClassPointer : public PPointer
|
||||
{
|
||||
DECLARE_CLASS(PClassPointer, PPointer);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PClassPointer(class PClass *restrict);
|
||||
|
||||
class PClass *ClassRestriction;
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
protected:
|
||||
PClassPointer();
|
||||
};
|
||||
|
||||
// Struct/class fields ------------------------------------------------------
|
||||
|
||||
// A PField describes a symbol that takes up physical space in the struct.
|
||||
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) {}
|
||||
|
||||
unsigned int Offset;
|
||||
PType *Type;
|
||||
DWORD Flags;
|
||||
protected:
|
||||
PField();
|
||||
};
|
||||
|
||||
// Compound types -----------------------------------------------------------
|
||||
|
||||
class PEnum : public PNamedType
|
||||
{
|
||||
DECLARE_CLASS(PEnum, PNamedType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PEnum(FName name, DObject *outer);
|
||||
|
||||
PType *ValueType;
|
||||
TMap<FName, int> Values;
|
||||
protected:
|
||||
PEnum();
|
||||
};
|
||||
|
||||
class PArray : public PCompoundType
|
||||
{
|
||||
DECLARE_CLASS(PArray, PCompoundType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PArray(PType *etype, unsigned int ecount);
|
||||
|
||||
PType *ElementType;
|
||||
unsigned int ElementCount;
|
||||
unsigned int ElementSize;
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
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);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PDynArray(PType *etype);
|
||||
|
||||
PType *ElementType;
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
protected:
|
||||
PDynArray();
|
||||
};
|
||||
|
||||
class PMap : public PCompoundType
|
||||
{
|
||||
DECLARE_CLASS(PMap, PCompoundType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PMap(PType *keytype, PType *valtype);
|
||||
|
||||
PType *KeyType;
|
||||
PType *ValueType;
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
protected:
|
||||
PMap();
|
||||
};
|
||||
|
||||
class PStruct : public PNamedType
|
||||
{
|
||||
DECLARE_CLASS(PStruct, PNamedType);
|
||||
public:
|
||||
PStruct(FName name, DObject *outer);
|
||||
|
||||
TArray<PField *> Fields;
|
||||
|
||||
PField *AddField(FName name, PType *type, DWORD flags=0);
|
||||
|
||||
size_t PropagateMark();
|
||||
protected:
|
||||
PStruct();
|
||||
};
|
||||
|
||||
class PPrototype : public PCompoundType
|
||||
{
|
||||
DECLARE_CLASS(PPrototype, PCompoundType);
|
||||
public:
|
||||
PPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
|
||||
|
||||
TArray<PType *> ArgumentTypes;
|
||||
TArray<PType *> ReturnTypes;
|
||||
|
||||
size_t PropagateMark();
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
protected:
|
||||
PPrototype();
|
||||
};
|
||||
|
||||
// TBD: Should we really support overloading?
|
||||
class PFunction : public PSymbol
|
||||
{
|
||||
DECLARE_CLASS(PFunction, PSymbol);
|
||||
public:
|
||||
struct Variant
|
||||
{
|
||||
PPrototype *Proto;
|
||||
VMFunction *Implementation;
|
||||
TArray<DWORD> ArgFlags; // Should be the same length as Proto->ArgumentTypes
|
||||
};
|
||||
TArray<Variant> Variants;
|
||||
DWORD Flags;
|
||||
|
||||
unsigned AddVariant(PPrototype *proto, TArray<DWORD> &argflags, VMFunction *impl);
|
||||
|
||||
size_t PropagateMark();
|
||||
|
||||
PFunction(FName name) : PSymbol(name), Flags(0) {}
|
||||
PFunction() : PSymbol(NAME_None), Flags(0) {}
|
||||
};
|
||||
|
||||
// Meta-info for every class derived from DObject ---------------------------
|
||||
|
||||
struct PClass
|
||||
class PClassClass;
|
||||
class PClass : public PStruct
|
||||
{
|
||||
static void StaticInit ();
|
||||
static void StaticShutdown ();
|
||||
static void StaticFreeData (PClass *type);
|
||||
static void ClearRuntimeData();
|
||||
DECLARE_CLASS(PClass, PStruct);
|
||||
HAS_OBJECT_POINTERS;
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
// We unravel _WITH_META here just as we did for PType.
|
||||
enum { MetaClassNum = CLASSREG_PClassClass };
|
||||
public:
|
||||
typedef PClassClass MetaClass;
|
||||
MetaClass *GetClass() const;
|
||||
|
||||
static void StaticInit();
|
||||
static void StaticShutdown();
|
||||
static void StaticBootstrap();
|
||||
|
||||
// Per-class information -------------------------------------
|
||||
FName TypeName; // this class's name
|
||||
unsigned int Size; // this class's size
|
||||
PClass *ParentClass; // the class this class derives from
|
||||
const size_t *Pointers; // object pointers defined by this class *only*
|
||||
const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default
|
||||
FActorInfo *ActorInfo;
|
||||
PClass *HashNext;
|
||||
FMetaTable Meta;
|
||||
BYTE *Defaults;
|
||||
bool bRuntimeClass; // class was defined at run-time, not compile-time
|
||||
unsigned short ClassIndex;
|
||||
PSymbolTable Symbols;
|
||||
|
||||
void (*ConstructNative)(void *);
|
||||
|
||||
// The rest are all functions and static data ----------------
|
||||
void InsertIntoHash ();
|
||||
DObject *CreateNew () const;
|
||||
PClass *CreateDerivedClass (FName name, unsigned int size);
|
||||
PClass();
|
||||
~PClass();
|
||||
void InsertIntoHash();
|
||||
DObject *CreateNew() const;
|
||||
PClass *CreateDerivedClass(FName name, unsigned int size);
|
||||
unsigned int Extend(unsigned int extension);
|
||||
void InitializeActorInfo ();
|
||||
void BuildFlatPointers ();
|
||||
void FreeStateList();
|
||||
void InitializeActorInfo();
|
||||
void BuildFlatPointers();
|
||||
const PClass *NativeClass() const;
|
||||
|
||||
// Returns true if this type is an ancestor of (or same as) the passed type.
|
||||
bool IsAncestorOf (const PClass *ti) const
|
||||
bool IsAncestorOf(const PClass *ti) const
|
||||
{
|
||||
while (ti)
|
||||
{
|
||||
|
@ -164,26 +647,160 @@ struct PClass
|
|||
}
|
||||
return false;
|
||||
}
|
||||
inline bool IsDescendantOf (const PClass *ti) const
|
||||
inline bool IsDescendantOf(const PClass *ti) const
|
||||
{
|
||||
return ti->IsAncestorOf (this);
|
||||
return ti->IsAncestorOf(this);
|
||||
}
|
||||
|
||||
// Find a type, given its name.
|
||||
static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); }
|
||||
static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); }
|
||||
static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); }
|
||||
static const PClass *FindClass (FName name);
|
||||
const PClass *FindClassTentative (FName name); // not static!
|
||||
PClass *GetReplacement() const;
|
||||
static PClass *FindClass(const char *name) { return FindClass(FName(name, true)); }
|
||||
static PClass *FindClass(const FString &name) { return FindClass(FName(name, true)); }
|
||||
static PClass *FindClass(ENamedName name) { return FindClass(FName(name)); }
|
||||
static PClass *FindClass(FName name);
|
||||
static PClassActor *FindActor(const char *name) { return FindActor(FName(name, true)); }
|
||||
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); // not static!
|
||||
|
||||
static TArray<PClass *> m_Types;
|
||||
static TArray<PClass *> m_RuntimeActors;
|
||||
|
||||
enum { HASH_SIZE = 256 };
|
||||
static PClass *TypeHash[HASH_SIZE];
|
||||
static TArray<PClass *> AllClasses;
|
||||
|
||||
static bool bShutdown;
|
||||
};
|
||||
|
||||
class PClassType : public PClass
|
||||
{
|
||||
DECLARE_CLASS(PClassType, PClass);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassType();
|
||||
|
||||
PClass *TypeTableType; // The type to use for hashing into the type table
|
||||
};
|
||||
|
||||
inline PType::MetaClass *PType::GetClass() const
|
||||
{
|
||||
return static_cast<MetaClass *>(DObject::GetClass());
|
||||
}
|
||||
|
||||
class PClassClass : public PClassType
|
||||
{
|
||||
DECLARE_CLASS(PClassClass, PClassType);
|
||||
public:
|
||||
PClassClass();
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
enum { HASH_SIZE = 1021 };
|
||||
|
||||
PType *TypeHash[HASH_SIZE];
|
||||
|
||||
PType *FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, size_t *bucketnum);
|
||||
void ReplaceType(PType *newtype, PType *oldtype, size_t bucket);
|
||||
void AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t parm2, size_t bucket);
|
||||
void AddType(PType *type);
|
||||
void Mark();
|
||||
void Clear();
|
||||
|
||||
static size_t Hash(const PClass *p1, intptr_t p2, intptr_t p3);
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
PClassPointer *NewClassPointer(PClass *restrict);
|
||||
PClassWaitingForParent *NewUnknownClass(FName myname, FName parentname);
|
||||
PEnum *NewEnum(FName name, DObject *outer);
|
||||
PStruct *NewStruct(FName name, DObject *outer);
|
||||
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
|
||||
|
||||
// Built-in types -----------------------------------------------------------
|
||||
|
||||
extern PErrorType *TypeError;
|
||||
extern PVoidType *TypeVoid;
|
||||
extern PInt *TypeSInt8, *TypeUInt8;
|
||||
extern PInt *TypeSInt16, *TypeUInt16;
|
||||
extern PInt *TypeSInt32, *TypeUInt32;
|
||||
extern PBool *TypeBool;
|
||||
extern PFloat *TypeFloat32, *TypeFloat64;
|
||||
extern PString *TypeString;
|
||||
extern PName *TypeName;
|
||||
extern PSound *TypeSound;
|
||||
extern PColor *TypeColor;
|
||||
extern PStatePointer *TypeState;
|
||||
extern PFixed *TypeFixed;
|
||||
extern PAngle *TypeAngle;
|
||||
|
||||
// A constant value ---------------------------------------------------------
|
||||
|
||||
class PSymbolConst : public PSymbol
|
||||
{
|
||||
DECLARE_CLASS(PSymbolConst, PSymbol);
|
||||
public:
|
||||
PType *ValueType;
|
||||
|
||||
PSymbolConst(FName name, PType *type=NULL) : PSymbol(name), ValueType(type) {}
|
||||
PSymbolConst() : PSymbol(NAME_None), ValueType(NULL) {}
|
||||
};
|
||||
|
||||
// A constant numeric value -------------------------------------------------
|
||||
|
||||
class PSymbolConstNumeric : public PSymbolConst
|
||||
{
|
||||
DECLARE_CLASS(PSymbolConstNumeric, PSymbolConst);
|
||||
public:
|
||||
union
|
||||
{
|
||||
int Value;
|
||||
double Float;
|
||||
void *Pad;
|
||||
};
|
||||
|
||||
PSymbolConstNumeric(FName name, PType *type=NULL) : PSymbolConst(name, type) {}
|
||||
PSymbolConstNumeric(FName name, PType *type, int val) : PSymbolConst(name, type), Value(val) {}
|
||||
PSymbolConstNumeric(FName name, PType *type, unsigned int val) : PSymbolConst(name, type), Value((int)val) {}
|
||||
PSymbolConstNumeric(FName name, PType *type, double val) : PSymbolConst(name, type), Float(val) {}
|
||||
PSymbolConstNumeric() {}
|
||||
};
|
||||
|
||||
// A constant string value --------------------------------------------------
|
||||
|
||||
class PSymbolConstString : public PSymbolConst
|
||||
{
|
||||
DECLARE_CLASS(PSymbolConstString, PSymbolConst);
|
||||
public:
|
||||
FString Str;
|
||||
|
||||
PSymbolConstString(FName name, FString &str) : PSymbolConst(name, TypeString), Str(str) {}
|
||||
PSymbolConstString() {}
|
||||
};
|
||||
|
||||
void ReleaseGlobalSymbols();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
#include "zstring.h"
|
||||
#include "vectors.h"
|
||||
|
||||
struct PClass;
|
||||
typedef TMap<int, const PClass *> FClassMap;
|
||||
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.
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
static cycle_t ThinkCycles;
|
||||
extern cycle_t BotSupportCycles;
|
||||
extern cycle_t ActionCycles;
|
||||
extern int BotWTG;
|
||||
|
||||
IMPLEMENT_CLASS (DThinker)
|
||||
|
@ -406,6 +407,7 @@ void DThinker::RunThinkers ()
|
|||
|
||||
ThinkCycles.Reset();
|
||||
BotSupportCycles.Reset();
|
||||
ActionCycles.Reset();
|
||||
BotWTG = 0;
|
||||
|
||||
ThinkCycles.Clock();
|
||||
|
@ -573,6 +575,6 @@ DThinker *FThinkerIterator::Next ()
|
|||
ADD_STAT (think)
|
||||
{
|
||||
FString out;
|
||||
out.Format ("Think time = %04.1f ms", ThinkCycles.TimeMS());
|
||||
out.Format ("Think time = %04.1f ms, Action = %04.1f ms", ThinkCycles.TimeMS(), ActionCycles.TimeMS());
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -121,10 +121,10 @@ public:
|
|||
template <class T> class TThinkerIterator : public FThinkerIterator
|
||||
{
|
||||
public:
|
||||
TThinkerIterator (int statnum=MAX_STATNUM+1) : FThinkerIterator (RUNTIME_CLASS(T), statnum)
|
||||
TThinkerIterator (int statnum=MAX_STATNUM+1) : FThinkerIterator (RUNTIME_TEMPLATE_CLASS(T), statnum)
|
||||
{
|
||||
}
|
||||
TThinkerIterator (int statnum, DThinker *prev) : FThinkerIterator (RUNTIME_CLASS(T), statnum, prev)
|
||||
TThinkerIterator (int statnum, DThinker *prev) : FThinkerIterator (RUNTIME_TEMPLATE_CLASS(T), statnum, prev)
|
||||
{
|
||||
}
|
||||
TThinkerIterator (const PClass *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(subclass, statnum)
|
||||
|
|
189
src/farchive.cpp
189
src/farchive.cpp
|
@ -662,12 +662,8 @@ FArchive::FArchive (FFile &file)
|
|||
|
||||
void FArchive::AttachToFile (FFile &file)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
m_HubTravel = false;
|
||||
m_File = &file;
|
||||
m_MaxObjectCount = m_ObjectCount = 0;
|
||||
m_ObjectMap = NULL;
|
||||
if (file.Mode() == FFile::EReading)
|
||||
{
|
||||
m_Loading = true;
|
||||
|
@ -679,19 +675,17 @@ void FArchive::AttachToFile (FFile &file)
|
|||
m_Storing = true;
|
||||
}
|
||||
m_Persistent = file.IsPersistent();
|
||||
m_TypeMap = NULL;
|
||||
m_TypeMap = new TypeMap[PClass::m_Types.Size()];
|
||||
for (i = 0; i < PClass::m_Types.Size(); i++)
|
||||
{
|
||||
m_TypeMap[i].toArchive = TypeMap::NO_INDEX;
|
||||
m_TypeMap[i].toCurrent = NULL;
|
||||
}
|
||||
m_ClassCount = 0;
|
||||
for (i = 0; i < EObjectHashSize; i++)
|
||||
{
|
||||
m_ObjectHash[i] = ~0;
|
||||
m_NameHash[i] = NameMap::NO_INDEX;
|
||||
}
|
||||
|
||||
ClassToArchive.Clear();
|
||||
ArchiveToClass.Clear();
|
||||
|
||||
ObjectToArchive.Clear();
|
||||
ArchiveToObject.Clear();
|
||||
|
||||
memset(m_NameHash, 0xFF, sizeof(m_NameHash));
|
||||
m_Names.Clear();
|
||||
m_NameStorage.Clear();
|
||||
|
||||
m_NumSprites = 0;
|
||||
m_SpriteMap = new int[sprites.Size()];
|
||||
for (size_t s = 0; s < sprites.Size(); ++s)
|
||||
|
@ -703,10 +697,6 @@ void FArchive::AttachToFile (FFile &file)
|
|||
FArchive::~FArchive ()
|
||||
{
|
||||
Close ();
|
||||
if (m_TypeMap)
|
||||
delete[] m_TypeMap;
|
||||
if (m_ObjectMap)
|
||||
M_Free (m_ObjectMap);
|
||||
if (m_SpriteMap)
|
||||
delete[] m_SpriteMap;
|
||||
}
|
||||
|
@ -727,7 +717,7 @@ void FArchive::Close ()
|
|||
{
|
||||
m_File->Close ();
|
||||
m_File = NULL;
|
||||
DPrintf ("Processed %u objects\n", m_ObjectCount);
|
||||
DPrintf ("Processed %u objects\n", ArchiveToObject.Size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1034,13 +1024,28 @@ FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
|
|||
|
||||
FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
|
||||
{
|
||||
if (IsStoring ())
|
||||
{
|
||||
return WriteObject (object);
|
||||
if (!type->IsDescendantOf(RUNTIME_CLASS(PClass)))
|
||||
{ // a regular object
|
||||
if (IsStoring())
|
||||
{
|
||||
return WriteObject(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadObject(object, type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadObject (object, type);
|
||||
{ // a class object
|
||||
if (IsStoring())
|
||||
{
|
||||
UserWriteClass((PClass *)object);
|
||||
}
|
||||
else
|
||||
{
|
||||
UserReadClass(object);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1068,7 +1073,8 @@ FArchive &FArchive::WriteObject (DObject *obj)
|
|||
}
|
||||
else
|
||||
{
|
||||
const PClass *type = RUNTIME_TYPE(obj);
|
||||
PClass *type = obj->GetClass();
|
||||
DWORD *classarcid;
|
||||
|
||||
if (type == RUNTIME_CLASS(DObject))
|
||||
{
|
||||
|
@ -1077,7 +1083,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
|
|||
id[0] = NULL_OBJ;
|
||||
Write (id, 1);
|
||||
}
|
||||
else if (m_TypeMap[type->ClassIndex].toArchive == TypeMap::NO_INDEX)
|
||||
else if (NULL == (classarcid = ClassToArchive.CheckKey(type)))
|
||||
{
|
||||
// No instances of this class have been written out yet.
|
||||
// Write out the class, then write out the object. If this
|
||||
|
@ -1110,9 +1116,9 @@ FArchive &FArchive::WriteObject (DObject *obj)
|
|||
// to the saved object. Otherwise, save a reference to the
|
||||
// class, then save the object. Again, if this is a player-
|
||||
// controlled actor, remember that.
|
||||
DWORD index = FindObjectIndex (obj);
|
||||
DWORD *objarcid = ObjectToArchive.CheckKey(obj);
|
||||
|
||||
if (index == TypeMap::NO_INDEX)
|
||||
if (objarcid == NULL)
|
||||
{
|
||||
|
||||
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
|
||||
|
@ -1128,7 +1134,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
|
|||
id[0] = NEW_OBJ;
|
||||
Write (id, 1);
|
||||
}
|
||||
WriteCount (m_TypeMap[type->ClassIndex].toArchive);
|
||||
WriteCount (*classarcid);
|
||||
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
|
||||
MapObject (obj);
|
||||
obj->SerializeUserVars (*this);
|
||||
|
@ -1139,7 +1145,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
|
|||
{
|
||||
id[0] = OLD_OBJ;
|
||||
Write (id, 1);
|
||||
WriteCount (index);
|
||||
WriteCount (*objarcid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1166,12 +1172,12 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
|
|||
break;
|
||||
|
||||
case OLD_OBJ:
|
||||
index = ReadCount ();
|
||||
if (index >= m_ObjectCount)
|
||||
index = ReadCount();
|
||||
if (index >= ArchiveToObject.Size())
|
||||
{
|
||||
I_Error ("Object reference too high (%u; max is %u)\n", index, m_ObjectCount);
|
||||
I_Error ("Object reference too high (%u; max is %u)\n", index, ArchiveToObject.Size());
|
||||
}
|
||||
obj = (DObject *)m_ObjectMap[index].object;
|
||||
obj = ArchiveToObject[index];
|
||||
break;
|
||||
|
||||
case NEW_PLYR_CLS_OBJ:
|
||||
|
@ -1386,24 +1392,19 @@ DWORD FArchive::FindName (const char *name, unsigned int bucket) const
|
|||
return (DWORD)map;
|
||||
}
|
||||
|
||||
DWORD FArchive::WriteClass (const PClass *info)
|
||||
DWORD FArchive::WriteClass (PClass *info)
|
||||
{
|
||||
if (m_ClassCount >= PClass::m_Types.Size())
|
||||
{
|
||||
I_Error ("Too many unique classes have been written.\nOnly %u were registered\n",
|
||||
PClass::m_Types.Size());
|
||||
}
|
||||
if (m_TypeMap[info->ClassIndex].toArchive != TypeMap::NO_INDEX)
|
||||
if (ClassToArchive.CheckKey(info) != NULL)
|
||||
{
|
||||
I_Error ("Attempt to write '%s' twice.\n", info->TypeName.GetChars());
|
||||
}
|
||||
m_TypeMap[info->ClassIndex].toArchive = m_ClassCount;
|
||||
m_TypeMap[m_ClassCount].toCurrent = info;
|
||||
DWORD index = ArchiveToClass.Push(info);
|
||||
ClassToArchive[info] = index;
|
||||
WriteString (info->TypeName.GetChars());
|
||||
return m_ClassCount++;
|
||||
return index;
|
||||
}
|
||||
|
||||
const PClass *FArchive::ReadClass ()
|
||||
PClass *FArchive::ReadClass ()
|
||||
{
|
||||
struct String {
|
||||
String() { val = NULL; }
|
||||
|
@ -1411,33 +1412,24 @@ const PClass *FArchive::ReadClass ()
|
|||
char *val;
|
||||
} typeName;
|
||||
|
||||
if (m_ClassCount >= PClass::m_Types.Size())
|
||||
{
|
||||
I_Error ("Too many unique classes have been read.\nOnly %u were registered\n",
|
||||
PClass::m_Types.Size());
|
||||
}
|
||||
operator<< (typeName.val);
|
||||
FName zaname(typeName.val, true);
|
||||
if (zaname != NAME_None)
|
||||
{
|
||||
for (unsigned int i = PClass::m_Types.Size(); i-- > 0; )
|
||||
PClass *type = PClass::FindClass(zaname);
|
||||
if (type != NULL)
|
||||
{
|
||||
if (PClass::m_Types[i]->TypeName == zaname)
|
||||
{
|
||||
m_TypeMap[i].toArchive = m_ClassCount;
|
||||
m_TypeMap[m_ClassCount].toCurrent = PClass::m_Types[i];
|
||||
m_ClassCount++;
|
||||
return PClass::m_Types[i];
|
||||
}
|
||||
ClassToArchive[type] = ArchiveToClass.Push(type);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
I_Error ("Unknown class '%s'\n", typeName.val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const PClass *FArchive::ReadClass (const PClass *wanttype)
|
||||
PClass *FArchive::ReadClass (const PClass *wanttype)
|
||||
{
|
||||
const PClass *type = ReadClass ();
|
||||
PClass *type = ReadClass ();
|
||||
if (!type->IsDescendantOf (wanttype))
|
||||
{
|
||||
I_Error ("Expected to extract an object of type '%s'.\n"
|
||||
|
@ -1447,14 +1439,10 @@ const PClass *FArchive::ReadClass (const PClass *wanttype)
|
|||
return type;
|
||||
}
|
||||
|
||||
const PClass *FArchive::ReadStoredClass (const PClass *wanttype)
|
||||
PClass *FArchive::ReadStoredClass (const PClass *wanttype)
|
||||
{
|
||||
DWORD index = ReadCount ();
|
||||
if (index >= m_ClassCount)
|
||||
{
|
||||
I_Error ("Class reference too high (%u; max is %u)\n", index, m_ClassCount);
|
||||
}
|
||||
const PClass *type = m_TypeMap[index].toCurrent;
|
||||
PClass *type = ArchiveToClass[index];
|
||||
if (!type->IsDescendantOf (wanttype))
|
||||
{
|
||||
I_Error ("Expected to extract an object of type '%s'.\n"
|
||||
|
@ -1464,47 +1452,14 @@ const PClass *FArchive::ReadStoredClass (const PClass *wanttype)
|
|||
return type;
|
||||
}
|
||||
|
||||
DWORD FArchive::MapObject (const DObject *obj)
|
||||
DWORD FArchive::MapObject (DObject *obj)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if (m_ObjectCount >= m_MaxObjectCount)
|
||||
{
|
||||
m_MaxObjectCount = m_MaxObjectCount ? m_MaxObjectCount * 2 : 1024;
|
||||
m_ObjectMap = (ObjectMap *)M_Realloc (m_ObjectMap, sizeof(ObjectMap)*m_MaxObjectCount);
|
||||
for (i = m_ObjectCount; i < m_MaxObjectCount; i++)
|
||||
{
|
||||
m_ObjectMap[i].hashNext = ~0;
|
||||
m_ObjectMap[i].object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD index = m_ObjectCount++;
|
||||
DWORD hash = HashObject (obj);
|
||||
|
||||
m_ObjectMap[index].object = obj;
|
||||
m_ObjectMap[index].hashNext = m_ObjectHash[hash];
|
||||
m_ObjectHash[hash] = index;
|
||||
|
||||
return index;
|
||||
DWORD i = ArchiveToObject.Push(obj);
|
||||
ObjectToArchive[obj] = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
DWORD FArchive::HashObject (const DObject *obj) const
|
||||
{
|
||||
return (DWORD)((size_t)obj % EObjectHashSize);
|
||||
}
|
||||
|
||||
DWORD FArchive::FindObjectIndex (const DObject *obj) const
|
||||
{
|
||||
DWORD index = m_ObjectHash[HashObject (obj)];
|
||||
while (index != TypeMap::NO_INDEX && m_ObjectMap[index].object != obj)
|
||||
{
|
||||
index = m_ObjectMap[index].hashNext;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void FArchive::UserWriteClass (const PClass *type)
|
||||
void FArchive::UserWriteClass (PClass *type)
|
||||
{
|
||||
BYTE id;
|
||||
|
||||
|
@ -1515,7 +1470,8 @@ void FArchive::UserWriteClass (const PClass *type)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (m_TypeMap[type->ClassIndex].toArchive == TypeMap::NO_INDEX)
|
||||
DWORD *arcid;
|
||||
if (NULL == (arcid = ClassToArchive.CheckKey(type)))
|
||||
{
|
||||
id = 1;
|
||||
Write (&id, 1);
|
||||
|
@ -1525,12 +1481,12 @@ void FArchive::UserWriteClass (const PClass *type)
|
|||
{
|
||||
id = 0;
|
||||
Write (&id, 1);
|
||||
WriteCount (m_TypeMap[type->ClassIndex].toArchive);
|
||||
WriteCount (*arcid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FArchive::UserReadClass (const PClass *&type)
|
||||
void FArchive::UserReadClass (PClass *&type)
|
||||
{
|
||||
BYTE newclass;
|
||||
|
||||
|
@ -1552,19 +1508,6 @@ void FArchive::UserReadClass (const PClass *&type)
|
|||
}
|
||||
}
|
||||
|
||||
FArchive &operator<< (FArchive &arc, const PClass * &info)
|
||||
{
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
arc.UserWriteClass (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.UserReadClass (info);
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FArchive &operator<< (FArchive &arc, sector_t *&sec)
|
||||
{
|
||||
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
|
||||
|
|
|
@ -170,8 +170,14 @@ virtual void Read (void *mem, unsigned int len);
|
|||
void WriteCount (DWORD count);
|
||||
DWORD ReadCount ();
|
||||
|
||||
void UserWriteClass (const PClass *info);
|
||||
void UserReadClass (const PClass *&info);
|
||||
void UserWriteClass (PClass *info);
|
||||
void UserReadClass (PClass *&info);
|
||||
template<typename T> void UserReadClass(T *&info)
|
||||
{
|
||||
PClass *myclass;
|
||||
UserReadClass(myclass);
|
||||
info = dyn_cast<T>(myclass);
|
||||
}
|
||||
|
||||
FArchive& operator<< (BYTE &c);
|
||||
FArchive& operator<< (WORD &s);
|
||||
|
@ -206,13 +212,11 @@ inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUN
|
|||
protected:
|
||||
enum { EObjectHashSize = 137 };
|
||||
|
||||
DWORD FindObjectIndex (const DObject *obj) const;
|
||||
DWORD MapObject (const DObject *obj);
|
||||
DWORD WriteClass (const PClass *info);
|
||||
const PClass *ReadClass ();
|
||||
const PClass *ReadClass (const PClass *wanttype);
|
||||
const PClass *ReadStoredClass (const PClass *wanttype);
|
||||
DWORD HashObject (const DObject *obj) const;
|
||||
DWORD MapObject (DObject *obj);
|
||||
DWORD WriteClass (PClass *info);
|
||||
PClass *ReadClass ();
|
||||
PClass *ReadClass (const PClass *wanttype);
|
||||
PClass *ReadStoredClass (const PClass *wanttype);
|
||||
DWORD AddName (const char *name);
|
||||
DWORD AddName (unsigned int start); // Name has already been added to storage
|
||||
DWORD FindName (const char *name) const;
|
||||
|
@ -223,24 +227,12 @@ protected:
|
|||
bool m_Storing; // inserting objects?
|
||||
bool m_HubTravel; // travelling inside a hub?
|
||||
FFile *m_File; // unerlying file object
|
||||
DWORD m_ObjectCount; // # of objects currently serialized
|
||||
DWORD m_MaxObjectCount;
|
||||
DWORD m_ClassCount; // # of unique classes currently serialized
|
||||
|
||||
struct TypeMap
|
||||
{
|
||||
const PClass *toCurrent; // maps archive type index to execution type index
|
||||
DWORD toArchive; // maps execution type index to archive type index
|
||||
TMap<PClass *, DWORD> ClassToArchive; // Maps PClass to archive type index
|
||||
TArray<PClass *> ArchiveToClass; // Maps archive type index to PClass
|
||||
|
||||
enum { NO_INDEX = 0xffffffff };
|
||||
} *m_TypeMap;
|
||||
|
||||
struct ObjectMap
|
||||
{
|
||||
const DObject *object;
|
||||
DWORD hashNext;
|
||||
} *m_ObjectMap;
|
||||
DWORD m_ObjectHash[EObjectHashSize];
|
||||
TMap<DObject *, DWORD> ObjectToArchive; // Maps objects to archive index
|
||||
TArray<DObject *> ArchiveToObject; // Maps archive index to objects
|
||||
|
||||
struct NameMap
|
||||
{
|
||||
|
@ -281,11 +273,9 @@ inline FArchive &operator<< (FArchive &arc, PalEntry &p)
|
|||
template<class T>
|
||||
inline FArchive &operator<< (FArchive &arc, T* &object)
|
||||
{
|
||||
return arc.SerializeObject ((DObject*&)object, RUNTIME_CLASS(T));
|
||||
return arc.SerializeObject ((DObject*&)object, RUNTIME_TEMPLATE_CLASS(T));
|
||||
}
|
||||
|
||||
FArchive &operator<< (FArchive &arc, const PClass * &info);
|
||||
|
||||
class FFont;
|
||||
FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font);
|
||||
template<> inline FArchive &operator<< <FFont> (FArchive &arc, FFont* &font)
|
||||
|
|
|
@ -10,5 +10,7 @@ class AActor;
|
|||
void T_PreprocessScripts();
|
||||
void T_LoadScripts(MapData * map);
|
||||
void T_AddSpawnedThing(AActor * );
|
||||
bool T_RunScript(int snum, AActor * t_trigger);
|
||||
void FS_Close();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -228,7 +228,7 @@ static const char * const ActorNames_init[]=
|
|||
"PointPuller",
|
||||
};
|
||||
|
||||
static const PClass * ActorTypes[countof(ActorNames_init)];
|
||||
static PClassActor * ActorTypes[countof(ActorNames_init)];
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -244,32 +244,32 @@ static const PClass * ActorTypes[countof(ActorNames_init)];
|
|||
// Doom index is only supported for the original things up to MBF
|
||||
//
|
||||
//==========================================================================
|
||||
const PClass * T_GetMobjType(svalue_t arg)
|
||||
PClassActor * T_GetMobjType(svalue_t arg)
|
||||
{
|
||||
const PClass * PClass=NULL;
|
||||
PClassActor * pclass=NULL;
|
||||
|
||||
if (arg.type==svt_string)
|
||||
{
|
||||
PClass=PClass::FindClass(arg.string);
|
||||
pclass=PClass::FindActor(arg.string);
|
||||
|
||||
// invalid object to spawn
|
||||
if(!PClass) script_error("unknown object type: %s\n", arg.string.GetChars());
|
||||
if(!pclass) script_error("unknown object type: %s\n", arg.string.GetChars());
|
||||
}
|
||||
else if (arg.type==svt_mobj)
|
||||
{
|
||||
AActor * mo = actorvalue(arg);
|
||||
if (mo) PClass = mo->GetClass();
|
||||
if (mo) pclass = mo->GetClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
int objtype = intvalue(arg);
|
||||
if (objtype>=0 && objtype<int(countof(ActorTypes))) PClass=ActorTypes[objtype];
|
||||
else PClass=NULL;
|
||||
if (objtype>=0 && objtype<int(countof(ActorTypes))) pclass=ActorTypes[objtype];
|
||||
else pclass=NULL;
|
||||
|
||||
// invalid object to spawn
|
||||
if(!PClass) script_error("unknown object type: %i\n", objtype);
|
||||
if(!pclass) script_error("unknown object type: %i\n", objtype);
|
||||
}
|
||||
return PClass;
|
||||
return pclass;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -341,7 +341,7 @@ inline int T_FindFirstSectorFromTag(int tagnum)
|
|||
// Doom index is only supported for the 4 original ammo types
|
||||
//
|
||||
//==========================================================================
|
||||
static const PClass * T_GetAmmo(const svalue_t &t)
|
||||
static PClassAmmo * T_GetAmmo(const svalue_t &t)
|
||||
{
|
||||
const char * p;
|
||||
|
||||
|
@ -362,8 +362,8 @@ static const PClass * T_GetAmmo(const svalue_t &t)
|
|||
}
|
||||
p=DefAmmo[ammonum];
|
||||
}
|
||||
const PClass * am=PClass::FindClass(p);
|
||||
if (!am->IsDescendantOf(RUNTIME_CLASS(AAmmo)))
|
||||
PClassAmmo * am=dyn_cast<PClassAmmo>(PClass::FindActor(p));
|
||||
if (am == NULL)
|
||||
{
|
||||
script_error("unknown ammo type : %s", p);
|
||||
return NULL;
|
||||
|
@ -861,12 +861,12 @@ void FParser::SF_Player(void)
|
|||
void FParser::SF_Spawn(void)
|
||||
{
|
||||
int x, y, z;
|
||||
const PClass *PClass;
|
||||
PClassActor *pclass;
|
||||
angle_t angle = 0;
|
||||
|
||||
if (CheckArgs(3))
|
||||
{
|
||||
if (!(PClass=T_GetMobjType(t_argv[0]))) return;
|
||||
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
|
||||
|
||||
x = fixedvalue(t_argv[1]);
|
||||
y = fixedvalue(t_argv[2]);
|
||||
|
@ -892,7 +892,7 @@ void FParser::SF_Spawn(void)
|
|||
}
|
||||
|
||||
t_return.type = svt_mobj;
|
||||
t_return.value.mobj = Spawn(PClass, x, y, z, ALLOW_REPLACE);
|
||||
t_return.value.mobj = Spawn(pclass, x, y, z, ALLOW_REPLACE);
|
||||
|
||||
if (t_return.value.mobj)
|
||||
{
|
||||
|
@ -2570,8 +2570,8 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
|
|||
{
|
||||
type = "BasicArmorPickup";
|
||||
}
|
||||
const PClass * info = PClass::FindClass (type);
|
||||
if (info == NULL || !info->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
PClassInventory * info = dyn_cast<PClassInventory>(PClass::FindActor (type));
|
||||
if (info == NULL)
|
||||
{
|
||||
Printf ("Unknown inventory item: %s\n", type);
|
||||
return;
|
||||
|
@ -2623,7 +2623,7 @@ static void FS_TakeInventory (AActor *actor, const char * type, int amount)
|
|||
{
|
||||
return;
|
||||
}
|
||||
const PClass * info = PClass::FindClass (type);
|
||||
PClassActor * info = PClass::FindActor (type);
|
||||
if (info == NULL)
|
||||
{
|
||||
return;
|
||||
|
@ -2672,7 +2672,7 @@ static int FS_CheckInventory (AActor *activator, const char *type)
|
|||
return activator->health;
|
||||
}
|
||||
|
||||
const PClass *info = PClass::FindClass (type);
|
||||
PClassActor *info = PClass::FindActor (type);
|
||||
AInventory *item = activator->FindInventory (info);
|
||||
return item ? item->Amount : 0;
|
||||
}
|
||||
|
@ -2732,7 +2732,7 @@ void FParser::SF_PlayerKeys(void)
|
|||
void FParser::SF_PlayerAmmo(void)
|
||||
{
|
||||
int playernum, amount;
|
||||
const PClass * ammotype;
|
||||
PClassAmmo * ammotype;
|
||||
|
||||
if (CheckArgs(2))
|
||||
{
|
||||
|
@ -2768,7 +2768,7 @@ void FParser::SF_PlayerAmmo(void)
|
|||
void FParser::SF_MaxPlayerAmmo()
|
||||
{
|
||||
int playernum, amount;
|
||||
const PClass * ammotype;
|
||||
PClassAmmo * ammotype;
|
||||
|
||||
if (CheckArgs(2))
|
||||
{
|
||||
|
@ -2843,7 +2843,7 @@ void FParser::SF_PlayerWeapon()
|
|||
script_error("weaponnum out of range! %s\n", weaponnum);
|
||||
return;
|
||||
}
|
||||
const PClass * ti = PClass::FindClass(WeaponNames[weaponnum]);
|
||||
PClassWeapon * ti = static_cast<PClassWeapon *>(PClass::FindActor(WeaponNames[weaponnum]));
|
||||
if (!ti)
|
||||
{
|
||||
script_error("incompatibility in playerweapon\n", weaponnum);
|
||||
|
@ -2924,7 +2924,7 @@ void FParser::SF_PlayerSelectedWeapon()
|
|||
script_error("weaponnum out of range! %s\n", weaponnum);
|
||||
return;
|
||||
}
|
||||
const PClass * ti = PClass::FindClass(WeaponNames[weaponnum]);
|
||||
PClassWeapon * ti = static_cast<PClassWeapon *>(PClass::FindActor(WeaponNames[weaponnum]));
|
||||
if (!ti)
|
||||
{
|
||||
script_error("incompatibility in playerweapon\n", weaponnum);
|
||||
|
@ -3028,7 +3028,7 @@ void FParser::SF_SetWeapon()
|
|||
int playernum=T_GetPlayerNum(t_argv[0]);
|
||||
if (playernum!=-1)
|
||||
{
|
||||
AInventory *item = players[playernum].mo->FindInventory (PClass::FindClass (stringvalue(t_argv[1])));
|
||||
AInventory *item = players[playernum].mo->FindInventory (PClass::FindActor (stringvalue(t_argv[1])));
|
||||
|
||||
if (item == NULL || !item->IsKindOf (RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
|
@ -3343,11 +3343,11 @@ void FParser::SF_SpawnExplosion()
|
|||
{
|
||||
fixed_t x, y, z;
|
||||
AActor* spawn;
|
||||
const PClass * PClass;
|
||||
PClassActor * pclass;
|
||||
|
||||
if (CheckArgs(3))
|
||||
{
|
||||
if (!(PClass=T_GetMobjType(t_argv[0]))) return;
|
||||
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
|
||||
|
||||
x = fixedvalue(t_argv[1]);
|
||||
y = fixedvalue(t_argv[2]);
|
||||
|
@ -3356,7 +3356,7 @@ void FParser::SF_SpawnExplosion()
|
|||
else
|
||||
z = P_PointInSector(x, y)->floorplane.ZatPoint(x,y);
|
||||
|
||||
spawn = Spawn (PClass, x, y, z, ALLOW_REPLACE);
|
||||
spawn = Spawn (pclass, x, y, z, ALLOW_REPLACE);
|
||||
t_return.type = svt_int;
|
||||
t_return.value.i=0;
|
||||
if (spawn)
|
||||
|
@ -3514,15 +3514,15 @@ void FParser::SF_SpawnMissile()
|
|||
{
|
||||
AActor *mobj;
|
||||
AActor *target;
|
||||
const PClass * PClass;
|
||||
PClassActor * pclass;
|
||||
|
||||
if (CheckArgs(3))
|
||||
{
|
||||
if (!(PClass=T_GetMobjType(t_argv[2]))) return;
|
||||
if (!(pclass=T_GetMobjType(t_argv[2]))) return;
|
||||
|
||||
mobj = actorvalue(t_argv[0]);
|
||||
target = actorvalue(t_argv[1]);
|
||||
if (mobj && target) P_SpawnMissile(mobj, target, PClass);
|
||||
if (mobj && target) P_SpawnMissile(mobj, target, pclass);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4150,7 +4150,7 @@ void FParser::SF_MobjHeight(void)
|
|||
|
||||
void FParser::SF_ThingCount(void)
|
||||
{
|
||||
const PClass *pClass;
|
||||
PClassActor *pClass;
|
||||
AActor * mo;
|
||||
int count=0;
|
||||
bool replacemented = false;
|
||||
|
@ -4161,7 +4161,7 @@ void FParser::SF_ThingCount(void)
|
|||
pClass=T_GetMobjType(t_argv[0]);
|
||||
if (!pClass) return;
|
||||
// If we want to count map items we must consider actor replacement
|
||||
pClass = pClass->ActorInfo->GetReplacement()->Class;
|
||||
pClass = pClass->GetReplacement();
|
||||
|
||||
again:
|
||||
TThinkerIterator<AActor> it;
|
||||
|
@ -4191,7 +4191,7 @@ again:
|
|||
{
|
||||
// Again, with decorate replacements
|
||||
replacemented = true;
|
||||
PClass *newkind = pClass->ActorInfo->GetReplacement()->Class;
|
||||
PClassActor *newkind = pClass->GetReplacement();
|
||||
if (newkind != pClass)
|
||||
{
|
||||
pClass = newkind;
|
||||
|
@ -4259,7 +4259,7 @@ void FParser::SF_SetColor(void)
|
|||
void FParser::SF_SpawnShot2(void)
|
||||
{
|
||||
AActor *source = NULL;
|
||||
const PClass * PClass;
|
||||
PClassActor * pclass;
|
||||
int z=0;
|
||||
|
||||
// t_argv[0] = type to spawn
|
||||
|
@ -4277,11 +4277,11 @@ void FParser::SF_SpawnShot2(void)
|
|||
|
||||
if(!source) return;
|
||||
|
||||
if (!(PClass=T_GetMobjType(t_argv[0]))) return;
|
||||
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
|
||||
|
||||
t_return.type = svt_mobj;
|
||||
|
||||
AActor *mo = Spawn (PClass, source->PosPlusZ(z), ALLOW_REPLACE);
|
||||
AActor *mo = Spawn (pclass, source->PosPlusZ(z), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM);
|
||||
|
@ -4606,7 +4606,7 @@ void init_functions(void)
|
|||
{
|
||||
for(unsigned i=0;i<countof(ActorNames_init);i++)
|
||||
{
|
||||
ActorTypes[i]=PClass::FindClass(ActorNames_init[i]);
|
||||
ActorTypes[i]=PClass::FindActor(ActorNames_init[i]);
|
||||
}
|
||||
|
||||
DFsScript * gscr = global_script;
|
||||
|
@ -4619,9 +4619,10 @@ void init_functions(void)
|
|||
gscr->NewVariable("trigger", svt_pMobj)->value.pMobj = &trigger_obj;
|
||||
|
||||
// Create constants for all existing line specials
|
||||
for(int i=0; i<256; i++)
|
||||
int max = P_GetMaxLineSpecial();
|
||||
for(int i=0; i<=max; i++)
|
||||
{
|
||||
const FLineSpecial *ls = LineSpecialsInfo[i];
|
||||
const FLineSpecial *ls = P_GetLineSpecialInfo(i);
|
||||
|
||||
if (ls != NULL && ls->max_args >= 0) // specials with max args set to -1 can only be used in a map and are of no use hee.
|
||||
{
|
||||
|
|
|
@ -621,7 +621,7 @@ void T_PreprocessScripts()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool RunScript(int snum, AActor * t_trigger)
|
||||
bool T_RunScript(int snum, AActor * t_trigger)
|
||||
{
|
||||
DFraggleThinker *th = DFraggleThinker::ActiveThinker;
|
||||
if (th)
|
||||
|
@ -649,44 +649,14 @@ static bool RunScript(int snum, AActor * t_trigger)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static int LS_FS_Execute (line_t *ln, AActor *it, bool backSide,
|
||||
int arg0, int arg1, int arg2, int arg3, int arg4)
|
||||
// FS_Execute(script#,firstsideonly,lock,msgtype)
|
||||
{
|
||||
if (arg1 && ln && backSide) return false;
|
||||
if (arg2!=0 && !P_CheckKeys(it, arg2, !!arg3)) return false;
|
||||
return RunScript(arg0,it);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FS_Close()
|
||||
{
|
||||
int i;
|
||||
DFsVariable *current, *next;
|
||||
|
||||
// we have to actually delete the global variables if we don't want
|
||||
// to get them reported as memory leaks.
|
||||
for(i=0; i<VARIABLESLOTS; i++)
|
||||
{
|
||||
current = global_script->variables[i];
|
||||
|
||||
while(current)
|
||||
{
|
||||
next = current->next; // save for after freeing
|
||||
|
||||
current->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete current;
|
||||
current = next; // go to next in chain
|
||||
}
|
||||
}
|
||||
GC::DelSoftRoot(global_script);
|
||||
global_script->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete global_script;
|
||||
if (global_script != NULL)
|
||||
{
|
||||
GC::DelSoftRoot(global_script);
|
||||
global_script->Destroy();
|
||||
global_script = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void T_Init()
|
||||
|
@ -695,12 +665,9 @@ void T_Init()
|
|||
|
||||
if (global_script == NULL)
|
||||
{
|
||||
// I'd rather link the special here than make another source file depend on FS!
|
||||
LineSpecials[FS_Execute]=LS_FS_Execute;
|
||||
global_script = new DFsScript;
|
||||
GC::AddSoftRoot(global_script);
|
||||
init_functions();
|
||||
atterm(FS_Close);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,6 +687,6 @@ CCMD(fpuke)
|
|||
}
|
||||
else
|
||||
{
|
||||
RunScript(atoi(argv[1]), players[consoleplayer].mo);
|
||||
T_RunScript(atoi(argv[1]), players[consoleplayer].mo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,18 +8,23 @@
|
|||
*/
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BspiAttack)
|
||||
{
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
|
||||
// launch a missile
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("ArachnotronPlasma"));
|
||||
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 (self);
|
||||
A_Chase (stack, self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ void A_Fire(AActor *self, int height);
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VileStart)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
S_Sound (self, CHAN_VOICE, "vile/start", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,22 +33,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileStart)
|
|||
//
|
||||
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)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_FIXED(height,0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_FIXED_OPT(height) { height = 0; }
|
||||
|
||||
A_Fire(self, height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void A_Fire(AActor *self, int height)
|
||||
|
@ -73,12 +80,13 @@ void A_Fire(AActor *self, int height)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(fire,0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(fire, AActor) { fire = PClass::FindActor("ArchvileFire"); }
|
||||
|
||||
AActor *fog;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
|
||||
|
@ -88,6 +96,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
|
|||
fog->target = self;
|
||||
fog->tracer = self->target;
|
||||
A_Fire(fog, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,25 +110,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
|
|||
#define VAF_DMGTYPEAPPLYTODIRECT 1
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
|
||||
{
|
||||
ACTION_PARAM_START(7);
|
||||
ACTION_PARAM_SOUND(snd,0);
|
||||
ACTION_PARAM_INT(dmg,1);
|
||||
ACTION_PARAM_INT(blastdmg,2);
|
||||
ACTION_PARAM_INT(blastrad,3);
|
||||
ACTION_PARAM_FIXED(thrust,4);
|
||||
ACTION_PARAM_NAME(dmgtype,5);
|
||||
ACTION_PARAM_INT(flags,6);
|
||||
{
|
||||
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_FIXED_OPT (thrust) { thrust = FRACUNIT; }
|
||||
PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; }
|
||||
PARAM_INT_OPT (flags) { flags = 0; }
|
||||
|
||||
AActor *fire, *target;
|
||||
|
||||
if (NULL == (target = self->target))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
|
||||
if (!P_CheckSight (self, target, 0) )
|
||||
return;
|
||||
return 0;
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);
|
||||
|
||||
|
@ -144,5 +153,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
|
|||
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
|
||||
}
|
||||
if (!(target->flags7 & MF7_DONTTHRUST))
|
||||
{
|
||||
target->velz = Scale(thrust, 1000, target->Mass);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,17 @@ 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 (fixed_t x, fixed_t y, fixed_t z)
|
||||
|
@ -35,16 +39,15 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
|
|||
boom->DeathSound = "misc/brainexplode";
|
||||
boom->velz = pr_brainscream() << 9;
|
||||
|
||||
const PClass *cls = PClass::FindClass("BossBrain");
|
||||
PClassActor *cls = PClass::FindActor("BossBrain");
|
||||
if (cls != NULL)
|
||||
{
|
||||
FState *state = cls->ActorInfo->FindState(NAME_Brainexplode);
|
||||
FState *state = cls->FindState(NAME_Brainexplode);
|
||||
if (state != NULL)
|
||||
boom->SetState (state);
|
||||
|
||||
}
|
||||
boom->effects = 0;
|
||||
boom->Damage = 0; // disables collision detection which is not wanted here
|
||||
boom->Damage = NULL; // disables collision detection which is not wanted here
|
||||
boom->tics -= pr_brainscream() & 7;
|
||||
if (boom->tics < 1)
|
||||
boom->tics = 1;
|
||||
|
@ -53,6 +56,7 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
fixed_t x;
|
||||
|
||||
for (x = self->X() - 196*FRACUNIT; x < self->X() + 320*FRACUNIT; x += 8*FRACUNIT)
|
||||
|
@ -61,20 +65,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
|
|||
128 + (pr_brainscream() << (FRACBITS + 1)));
|
||||
}
|
||||
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
fixed_t x = self->X() + pr_brainexplode.Random2()*2048;
|
||||
fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT;
|
||||
BrainishExplosion (x, self->Y(), z);
|
||||
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;
|
||||
return 0;
|
||||
|
||||
// New dmflag: Kill all boss spawned monsters before ending the level.
|
||||
if (dmflags2 & DF2_KILLBOSSMONST)
|
||||
|
@ -98,18 +107,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
|
||||
// shoot a cube at current target
|
||||
targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));
|
||||
|
||||
|
@ -117,7 +127,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
|
|||
{
|
||||
if (spawntype == NULL)
|
||||
{
|
||||
spawntype = PClass::FindClass("SpawnShot");
|
||||
spawntype = PClass::FindActor("SpawnShot");
|
||||
isdefault = true;
|
||||
}
|
||||
|
||||
|
@ -161,9 +171,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
|
|||
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
||||
static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound)
|
||||
{
|
||||
AActor *newmobj;
|
||||
AActor *fog;
|
||||
|
@ -191,8 +202,8 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
|||
|
||||
FName SpawnName;
|
||||
|
||||
FDropItem *di; // di will be our drop item list iterator
|
||||
FDropItem *drop; // while drop stays as the reference point.
|
||||
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
|
||||
|
@ -208,11 +219,11 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
|||
{
|
||||
if (di->Name != NAME_None)
|
||||
{
|
||||
if (di->amount < 0)
|
||||
if (di->Amount < 0)
|
||||
{
|
||||
di->amount = 1; // default value is -1, we need a positive value.
|
||||
di->Amount = 1; // default value is -1, we need a positive value.
|
||||
}
|
||||
n += di->amount; // this is how we can weight the list.
|
||||
n += di->Amount; // this is how we can weight the list.
|
||||
}
|
||||
}
|
||||
di = drop;
|
||||
|
@ -221,7 +232,7 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
|||
{
|
||||
if (di->Name != NAME_None)
|
||||
{
|
||||
n -= di->amount; // logically, none of the -1 values have survived by now.
|
||||
n -= di->Amount; // logically, none of the -1 values have survived by now.
|
||||
}
|
||||
if ((di->Next != NULL) && (n >= 0))
|
||||
{
|
||||
|
@ -253,7 +264,7 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
|||
else if (r < 246) SpawnName = "HellKnight";
|
||||
else SpawnName = "BaronOfHell";
|
||||
}
|
||||
spawntype = PClass::FindClass(SpawnName);
|
||||
spawntype = PClass::FindActor(SpawnName);
|
||||
if (spawntype != NULL)
|
||||
{
|
||||
newmobj = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE);
|
||||
|
@ -287,10 +298,10 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
|
||||
{
|
||||
FSoundID sound;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
FSoundID sound;
|
||||
|
||||
if (spawntype != NULL)
|
||||
{
|
||||
|
@ -298,15 +309,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
|
|||
}
|
||||
else
|
||||
{
|
||||
spawntype = PClass::FindClass ("SpawnFire");
|
||||
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::FindClass("SpawnFire"), "brain/spawn");
|
||||
SpawnFly(self, PClass::FindActor("SpawnFire"), "brain/spawn");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ static FRandom pr_bruisattack ("BruisAttack");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (self->CheckMeleeRange ())
|
||||
{
|
||||
|
@ -12,9 +14,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// launch a missile
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("BaronBall"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("BaronBall"));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,10 @@ static FRandom pr_headattack ("HeadAttack");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -24,9 +26,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// launch a missile
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("CacodemonBall"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("CacodemonBall"));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,15 +9,21 @@
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CyberAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("Rocket"));
|
||||
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 (self);
|
||||
A_Chase (stack, self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ static FRandom pr_sargattack ("SargAttack");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -23,4 +25,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
|
|||
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
|
||||
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
void BeginPlay ();
|
||||
void Tick ();
|
||||
void SetWeapon (EMarineWeapon);
|
||||
void SetSprite (const PClass *source);
|
||||
void SetSprite (PClassActor *source);
|
||||
void Serialize (FArchive &arc);
|
||||
|
||||
int CurrentWeapon;
|
||||
|
|
|
@ -17,8 +17,10 @@ static FRandom pr_troopattack ("TroopAttack");
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -27,9 +29,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// launch a missile
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("DoomImpBall"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("DoomImpBall"));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (dmflags2 & DF2_BARRELS_RESPAWN)
|
||||
{
|
||||
self->height = self->GetDefault()->height;
|
||||
|
@ -48,4 +50,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
|
|||
{
|
||||
self->Destroy ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ static FRandom pr_oldbfg ("OldBFG");
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int pitch;
|
||||
|
@ -39,7 +41,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
|||
if (weapon != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +63,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
|||
S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
|
||||
self->angle = self->AngleTo(linetarget);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -68,6 +71,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
bool accurate;
|
||||
|
||||
if (self->player != NULL)
|
||||
|
@ -76,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
|
|||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
P_SetPsprite (self->player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
}
|
||||
|
@ -91,7 +96,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
|
|||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
|
||||
|
||||
P_GunShot (self, accurate, PClass::FindClass(NAME_BulletPuff), P_BulletSlope (self));
|
||||
P_GunShot (self, accurate, PClass::FindActor(NAME_BulletPuff), P_BulletSlope (self));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -111,62 +117,70 @@ enum SAW_Flags
|
|||
|
||||
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_FIXED_OPT (range) { range = 0; }
|
||||
PARAM_ANGLE_OPT (spread_xy) { spread_xy = angle_t(2.8125 * (ANGLE_90 / 90.0)); }
|
||||
PARAM_ANGLE_OPT (spread_z) { spread_z = 0; }
|
||||
PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; }
|
||||
PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; }
|
||||
PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; }
|
||||
|
||||
angle_t angle;
|
||||
angle_t slope;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
int actualdamage;
|
||||
|
||||
ACTION_PARAM_START(11);
|
||||
ACTION_PARAM_SOUND(fullsound, 0);
|
||||
ACTION_PARAM_SOUND(hitsound, 1);
|
||||
ACTION_PARAM_INT(damage, 2);
|
||||
ACTION_PARAM_CLASS(pufftype, 3);
|
||||
ACTION_PARAM_INT(Flags, 4);
|
||||
ACTION_PARAM_FIXED(Range, 5);
|
||||
ACTION_PARAM_ANGLE(Spread_XY, 6);
|
||||
ACTION_PARAM_ANGLE(Spread_Z, 7);
|
||||
ACTION_PARAM_FIXED(LifeSteal, 8);
|
||||
ACTION_PARAM_INT(lifestealmax, 9);
|
||||
ACTION_PARAM_CLASS(armorbonustype, 10);
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff);
|
||||
if (damage == 0) damage = 2;
|
||||
|
||||
if (!(Flags & SF_NORANDOM))
|
||||
if (pufftype == NULL)
|
||||
{
|
||||
pufftype = PClass::FindActor(NAME_BulletPuff);
|
||||
}
|
||||
if (damage == 0)
|
||||
{
|
||||
damage = 2;
|
||||
}
|
||||
if (!(flags & SF_NORANDOM))
|
||||
{
|
||||
damage *= (pr_saw()%10+1);
|
||||
|
||||
// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
|
||||
if (Range == 0) Range = MELEERANGE+1;
|
||||
}
|
||||
if (range == 0)
|
||||
{ // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
|
||||
range = MELEERANGE+1;
|
||||
}
|
||||
|
||||
angle = self->angle + (pr_saw.Random2() * (Spread_XY / 255));
|
||||
slope = P_AimLineAttack (self, angle, Range, &linetarget) + (pr_saw.Random2() * (Spread_Z / 255));
|
||||
angle = self->angle + (pr_saw.Random2() * (spread_xy / 255));
|
||||
slope = P_AimLineAttack (self, angle, range, &linetarget) + (pr_saw.Random2() * (spread_z / 255));
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if ((weapon != NULL) && !(Flags & SF_NOUSEAMMO) && !(!linetarget && (Flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
P_LineAttack (self, angle, Range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);
|
||||
P_LineAttack (self, angle, range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);
|
||||
|
||||
if (!linetarget)
|
||||
{
|
||||
if ((Flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64))
|
||||
if ((flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64))
|
||||
{
|
||||
player->extralight = !player->extralight;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Flags & SF_RANDOMLIGHTHIT)
|
||||
if (flags & SF_RANDOMLIGHTHIT)
|
||||
{
|
||||
int randVal = pr_saw();
|
||||
if (randVal < 64)
|
||||
|
@ -183,16 +197,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
}
|
||||
}
|
||||
|
||||
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
|
||||
if (lifesteal && !(linetarget->flags5 & MF5_DONTDRAIN))
|
||||
{
|
||||
if (Flags & SF_STEALARMOR)
|
||||
if (flags & SF_STEALARMOR)
|
||||
{
|
||||
if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus");
|
||||
|
||||
if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
if (armorbonustype == NULL)
|
||||
{
|
||||
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE));
|
||||
armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS;
|
||||
armorbonustype = dyn_cast<ABasicArmorBonus::MetaClass>(PClass::FindClass("ArmorBonus"));
|
||||
}
|
||||
if (armorbonustype != NULL)
|
||||
{
|
||||
assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)));
|
||||
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype, 0,0,0, NO_REPLACE));
|
||||
armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS;
|
||||
armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
|
||||
armorbonus->flags |= MF_DROPPED;
|
||||
armorbonus->ClearCounters();
|
||||
|
@ -206,14 +223,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
|
||||
else
|
||||
{
|
||||
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS, lifestealmax);
|
||||
P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax);
|
||||
}
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
|
||||
|
||||
// turn to face target
|
||||
if (!(Flags & SF_NOTURN))
|
||||
if (!(flags & SF_NOTURN))
|
||||
{
|
||||
angle = self->AngleTo(linetarget);
|
||||
if (angle - self->angle > ANG180)
|
||||
|
@ -231,8 +248,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
self->angle += ANG90 / 20;
|
||||
}
|
||||
}
|
||||
if (!(Flags & SF_NOPULLIN))
|
||||
if (!(flags & SF_NOPULLIN))
|
||||
self->flags |= MF_JUSTATTACKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -240,12 +258,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
|
||||
|
@ -253,15 +273,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
|
|||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
}
|
||||
player->mo->PlayAttacking2 ();
|
||||
|
||||
angle_t pitch = P_BulletSlope (self);
|
||||
|
||||
for (i=0 ; i<7 ; i++)
|
||||
P_GunShot (self, false, PClass::FindClass(NAME_BulletPuff), pitch);
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
P_GunShot (self, false, PClass::FindActor(NAME_BulletPuff), pitch);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -269,6 +292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
angle_t angle;
|
||||
int damage;
|
||||
|
@ -276,7 +301,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
|
||||
|
@ -284,7 +309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
|
|||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2))
|
||||
return;
|
||||
return 0;
|
||||
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
}
|
||||
player->mo->PlayAttacking2 ();
|
||||
|
@ -310,22 +335,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
|
|||
pitch + (pr_fireshotgun2.Random2() * 332063), 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -341,15 +373,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2)
|
|||
void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int index)
|
||||
{
|
||||
|
||||
const PClass * cls = weapon->GetClass();
|
||||
PClassActor *cls = weapon->GetClass();
|
||||
while (cls != RUNTIME_CLASS(AWeapon))
|
||||
{
|
||||
FActorInfo * info = cls->ActorInfo;
|
||||
if (flashstate >= info->OwnedStates && flashstate < info->OwnedStates + info->NumOwnedStates)
|
||||
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 < info->OwnedStates + info->NumOwnedStates)
|
||||
if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates)
|
||||
{
|
||||
// we're ok so set the state
|
||||
P_SetPsprite (player, ps_flash, flashstate + index);
|
||||
|
@ -363,7 +394,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i
|
|||
}
|
||||
}
|
||||
// try again with parent class
|
||||
cls = cls->ParentClass;
|
||||
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.
|
||||
|
@ -382,18 +413,20 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (self == NULL || NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
|
||||
|
||||
|
@ -416,7 +449,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
|
|||
}
|
||||
player->mo->PlayAttacking2 ();
|
||||
|
||||
P_GunShot (self, !player->refire, PClass::FindClass(NAME_BulletPuff), P_BulletSlope (self));
|
||||
P_GunShot (self, !player->refire, PClass::FindActor(NAME_BulletPuff), P_BulletSlope (self));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -424,19 +458,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("Rocket"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("Rocket"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -444,20 +481,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(grenade, AActor) { grenade = PClass::FindActor("Grenade"); }
|
||||
|
||||
player_t *player;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(grenade, 0);
|
||||
if (grenade == NULL) return;
|
||||
|
||||
if (grenade == NULL)
|
||||
return 0;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Temporarily raise the pitch to send the grenade slightly upwards
|
||||
|
@ -465,6 +505,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
|
|||
self->pitch -= (1152 << FRACBITS);
|
||||
P_SpawnPlayerMissile(self, grenade);
|
||||
self->pitch = SavedPlayerPitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -472,17 +513,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
FState *flash = weapon->FindState(NAME_Flash);
|
||||
if (flash != NULL)
|
||||
|
@ -491,7 +534,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma)
|
|||
}
|
||||
}
|
||||
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("PlasmaBall"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("PlasmaBall"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -528,22 +572,29 @@ static void FireRailgun(AActor *self, int offset_xy, bool fromweapon)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, 0, ACTION_CALL_FROM_WEAPON());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunRight)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, 10, ACTION_CALL_FROM_WEAPON());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunLeft)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, -10, ACTION_CALL_FROM_WEAPON());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RailWait)
|
||||
{
|
||||
// Okay, this was stupid. Just use a NULL function instead of this.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -552,21 +603,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_RailWait)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, deh.BFGCells))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindClass("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
|
||||
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -576,22 +630,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT (spraytype, AActor) { spraytype = NULL; }
|
||||
PARAM_INT_OPT (numrays) { numrays = 40; }
|
||||
PARAM_INT_OPT (damagecnt) { damagecnt = 15; }
|
||||
PARAM_ANGLE_OPT (angle) { angle = ANGLE_90; }
|
||||
PARAM_FIXED_OPT (distance) { distance = 16*64*FRACUNIT; }
|
||||
PARAM_ANGLE_OPT (vrange) { vrange = 32*FRACUNIT; }
|
||||
PARAM_INT_OPT (defdamage) { defdamage = 0; }
|
||||
|
||||
int i;
|
||||
int j;
|
||||
int damage;
|
||||
angle_t an;
|
||||
AActor *linetarget;
|
||||
|
||||
ACTION_PARAM_START(7);
|
||||
ACTION_PARAM_CLASS(spraytype, 0);
|
||||
ACTION_PARAM_INT(numrays, 1);
|
||||
ACTION_PARAM_INT(damagecnt, 2);
|
||||
ACTION_PARAM_ANGLE(angle, 3);
|
||||
ACTION_PARAM_FIXED(distance, 4);
|
||||
ACTION_PARAM_ANGLE(vrange, 5);
|
||||
ACTION_PARAM_INT(defdamage, 6);
|
||||
|
||||
if (spraytype == NULL) spraytype = PClass::FindClass("BFGExtra");
|
||||
if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
|
||||
if (numrays <= 0) numrays = 40;
|
||||
if (damagecnt <= 0) damagecnt = 15;
|
||||
if (angle == 0) angle = ANG90;
|
||||
|
@ -600,7 +654,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
|
||||
// [RH] Don't crash if no target
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
// offset angles from its attack angle
|
||||
for (i = 0; i < numrays; i++)
|
||||
|
@ -646,6 +700,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
P_TraceBleed(newdam > 0 ? newdam : damage, linetarget, self->target);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -653,7 +708,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -667,7 +724,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
||||
{
|
||||
const PClass * plasma[] = {PClass::FindClass("PlasmaBall1"), PClass::FindClass("PlasmaBall2")};
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PClassActor *plasma[] = { PClass::FindActor("PlasmaBall1"), PClass::FindActor("PlasmaBall2") };
|
||||
AActor * mo = NULL;
|
||||
|
||||
player_t *player;
|
||||
|
@ -675,7 +733,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
|
@ -683,7 +741,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
|||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
doesautoaim = !(weapon->WeaponFlags & WIF_NOAUTOAIM);
|
||||
weapon->WeaponFlags |= WIF_NOAUTOAIM; // No autoaiming that gun
|
||||
|
@ -702,5 +760,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
|||
self->angle = SavedPlayerAngle;
|
||||
self->pitch = SavedPlayerPitch;
|
||||
}
|
||||
if (doesautoaim && weapon != NULL) weapon->WeaponFlags &= ~WIF_NOAUTOAIM; // Restore autoaim setting
|
||||
if (doesautoaim && weapon != NULL)
|
||||
{ // Restore autoaim setting
|
||||
weapon->WeaponFlags &= ~WIF_NOAUTOAIM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,22 +19,25 @@
|
|||
|
||||
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;
|
||||
angle_t an;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
||||
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
|
||||
|
||||
A_FaceTarget (self);
|
||||
// Change direction to ...
|
||||
|
@ -49,20 +52,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
|
|||
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
||||
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
|
||||
|
||||
AActor *missile;
|
||||
angle_t an;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
||||
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
|
||||
|
||||
A_FaceTarget (self);
|
||||
// Now here choose opposite deviation.
|
||||
|
@ -77,20 +81,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
|
|||
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
||||
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
|
||||
|
||||
AActor *missile;
|
||||
angle_t an;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
||||
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
|
||||
|
||||
A_FaceTarget (self);
|
||||
|
||||
|
@ -111,6 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
|
|||
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
||||
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -118,8 +124,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
|
|||
// Original idea: Linguica
|
||||
//
|
||||
|
||||
AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const PClass *type);
|
||||
|
||||
enum
|
||||
{
|
||||
MSF_Standard = 0,
|
||||
|
@ -129,17 +133,23 @@ enum
|
|||
|
||||
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_FIXED_OPT (vrange) { vrange = 4*FRACUNIT; }
|
||||
PARAM_FIXED_OPT (hrange) { hrange = FRACUNIT/2; }
|
||||
|
||||
int i, j;
|
||||
|
||||
ACTION_PARAM_START(5);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
ACTION_PARAM_INT(n, 1);
|
||||
ACTION_PARAM_INT(flags, 2);
|
||||
ACTION_PARAM_FIXED(vrange, 3);
|
||||
ACTION_PARAM_FIXED(hrange, 4);
|
||||
|
||||
if (n == 0) n = self->Damage; // GetMissileDamage (0, 1);
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
||||
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<<FRACBITS);
|
||||
|
@ -176,4 +186,5 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
|
|||
}
|
||||
}
|
||||
target->Destroy();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
// 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
|
||||
|
@ -27,14 +31,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie)
|
|||
if (other != self && other->health > 0 && other->IsA (matchClass))
|
||||
{
|
||||
// other Keen not dead
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(doortag, 0);
|
||||
|
||||
EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2*FRACUNIT, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,22 +46,27 @@ void A_SkullAttack(AActor *self, fixed_t speed)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_FIXED(n, 0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_FIXED_OPT(speed) { speed = SKULLSPEED; }
|
||||
|
||||
if (n <= 0) n = SKULLSPEED;
|
||||
A_SkullAttack(self, n);
|
||||
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;
|
||||
return 0;
|
||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
||||
A_FaceTarget(self);
|
||||
damage = (pr_oldsoul()%8+1)*self->Damage;
|
||||
damage = (pr_oldsoul()%8+1)*self->GetMissileDamage(0,1);
|
||||
P_DamageMobj(self->target, self, self, damage, NAME_None);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,13 +12,22 @@
|
|||
|
||||
DECLARE_ACTION(A_SkullAttack)
|
||||
|
||||
static const PClass *GetSpawnType(DECLARE_PARAMINFO)
|
||||
static PClassActor *GetSpawnType(VMValue *param)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
PClassActor *spawntype;
|
||||
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");
|
||||
return spawntype;
|
||||
if (param == NULL || param->Type == REGT_NIL)
|
||||
{
|
||||
spawntype = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(param->Type == REGT_POINTER);
|
||||
assert(param->atag == ATAG_OBJECT || param->a == NULL);
|
||||
spawntype = (PClassActor *)param->a;
|
||||
}
|
||||
|
||||
return (spawntype != NULL) ? spawntype : PClass::FindActor("LostSoul");
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,13 +42,13 @@ enum PA_Flags
|
|||
// A_PainShootSkull
|
||||
// Spawn a lost soul and launch it at the target
|
||||
//
|
||||
void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype, int flags = 0, int limit = -1)
|
||||
void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int flags = 0, int limit = -1)
|
||||
{
|
||||
AActor *other;
|
||||
int prestep;
|
||||
|
||||
if (spawntype == NULL) return;
|
||||
if (self->DamageType==NAME_Massacre) return;
|
||||
if (self->DamageType == NAME_Massacre) return;
|
||||
|
||||
// [RH] check to make sure it's not too close to the ceiling
|
||||
if (self->Top() + 8*FRACUNIT > self->ceilingz)
|
||||
|
@ -163,42 +172,50 @@ void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype, int
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ACTION_PARAM_START(4);
|
||||
ACTION_PARAM_CLASS(spawntype, 0);
|
||||
ACTION_PARAM_ANGLE(angle, 1);
|
||||
ACTION_PARAM_INT(flags, 2);
|
||||
ACTION_PARAM_INT(limit, 3);
|
||||
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 (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");
|
||||
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
|
||||
|
||||
if (!(flags & PAF_AIMFACING))
|
||||
A_FaceTarget (self);
|
||||
A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
|
||||
{
|
||||
if (!self->target)
|
||||
return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO);
|
||||
if (!self->target)
|
||||
return 0;
|
||||
|
||||
PClassActor *spawntype = GetSpawnType(numparam > NAP ? ¶m[NAP] : NULL);
|
||||
A_FaceTarget (self);
|
||||
A_PainShootSkull (self, self->angle + ANG45, spawntype);
|
||||
A_PainShootSkull (self, self->angle - ANG45, spawntype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
|
||||
{
|
||||
if (self->target != NULL && self->IsFriend (self->target))
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target != NULL && self->IsFriend(self->target))
|
||||
{ // And I thought you were my friend!
|
||||
self->flags &= ~MF_FRIENDLY;
|
||||
}
|
||||
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO);
|
||||
PClassActor *spawntype = GetSpawnType(numparam > NAP ? ¶m[NAP] : NULL);
|
||||
A_Unblock(self, true);
|
||||
A_PainShootSkull (self, self->angle + ANG90, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG180, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG270, spawntype);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,14 @@ static FRandom pr_cposrefire ("CPosRefire");
|
|||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
angle = self->angle;
|
||||
|
@ -35,6 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
|
|||
angle += pr_posattack.Random2() << 20;
|
||||
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)
|
||||
|
@ -57,33 +60,41 @@ static void A_SPosAttack2 (AActor *self)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SPosAttackUseAtkSound)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
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;
|
||||
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;
|
||||
|
||||
int angle;
|
||||
int bangle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (self->flags & MF_STEALTH)
|
||||
|
@ -99,15 +110,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
|
|||
angle = bangle + (pr_cposattack.Random2() << 20);
|
||||
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;
|
||||
return 0;
|
||||
|
||||
if (!self->target
|
||||
|| P_HitFriend (self)
|
||||
|
@ -116,4 +130,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire)
|
|||
{
|
||||
self->SetState (self->SeeState);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,27 +19,32 @@ static FRandom pr_skelfist ("SkelFist");
|
|||
// A_SkelMissile
|
||||
//
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile)
|
||||
{
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *missile;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
missile = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT,
|
||||
self->target, PClass::FindClass("RevenantTracer"));
|
||||
self->target, PClass::FindActor("RevenantTracer"));
|
||||
|
||||
if (missile != NULL)
|
||||
{
|
||||
missile->SetOrigin(missile->Vec3Offset(missile->velx, missile->vely, 0), false);
|
||||
missile->tracer = self->target;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TRACEANGLE (0xc000000)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t exact;
|
||||
fixed_t dist;
|
||||
fixed_t slope;
|
||||
|
@ -56,10 +61,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
|
|||
// [RH] level.time is always 0-based, so nothing special to do here.
|
||||
|
||||
if (level.time & 3)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
// spawn a puff of smoke behind the rocket
|
||||
P_SpawnPuff (self, PClass::FindClass(NAME_BulletPuff), self->X(), self->Y(), self->Z(), 0, 3);
|
||||
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->X(), self->Y(), self->Z(), 0, 3);
|
||||
|
||||
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);
|
||||
|
||||
|
@ -72,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
|
|||
dest = self->tracer;
|
||||
|
||||
if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
// change angle
|
||||
exact = self->AngleTo(dest);
|
||||
|
@ -119,21 +124,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
|
|||
else
|
||||
self->velz += FRACUNIT/8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SkelWhoosh)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
return;
|
||||
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;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
|
||||
|
@ -144,4 +155,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelFist)
|
|||
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
|
||||
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -155,8 +155,8 @@ void AScriptedMarine::Tick ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(ignoremissile, 0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_BOOL_OPT(ignoremissile) { ignoremissile = false; }
|
||||
|
||||
if (self->target == NULL || self->target->health <= 0)
|
||||
{
|
||||
|
@ -164,11 +164,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
|
|||
{ // 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;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
self->SetState (self->state + 1);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (((ignoremissile || self->MissileState == NULL) && !self->CheckMeleeRange ()) ||
|
||||
!P_CheckSight (self, self->target) ||
|
||||
|
@ -176,6 +176,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
|
|||
{
|
||||
self->SetState (self->state + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -186,15 +187,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_SawRefire)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL || self->target->health <= 0)
|
||||
{
|
||||
self->SetState (self->state + 1);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!self->CheckMeleeRange ())
|
||||
{
|
||||
self->SetState (self->state + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -205,10 +209,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_SawRefire)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -219,8 +226,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MarineNoise)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MarineChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
CALL_ACTION(A_MarineNoise, self);
|
||||
A_Chase (self);
|
||||
A_Chase (stack, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -231,8 +240,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MarineChase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MarineLook)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
CALL_ACTION(A_MarineNoise, self);
|
||||
CALL_ACTION(A_Look, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -243,17 +254,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_MarineLook)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
|
||||
{
|
||||
ACTION_PARAM_START(4);
|
||||
ACTION_PARAM_SOUND(fullsound, 0);
|
||||
ACTION_PARAM_SOUND(hitsound, 1);
|
||||
ACTION_PARAM_INT(damage, 2);
|
||||
ACTION_PARAM_CLASS(pufftype, 3);
|
||||
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;
|
||||
return 0;
|
||||
|
||||
if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff);
|
||||
if (damage == 0) damage = 2;
|
||||
if (pufftype == NULL)
|
||||
{
|
||||
pufftype = PClass::FindActor(NAME_BulletPuff);
|
||||
}
|
||||
if (damage == 0)
|
||||
{
|
||||
damage = 2;
|
||||
}
|
||||
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -271,7 +288,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
|
|||
if (!linetarget)
|
||||
{
|
||||
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
|
||||
|
||||
|
@ -297,6 +314,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
|
|||
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
|
||||
}
|
||||
//A_Chase (self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -333,10 +351,11 @@ static void MarinePunch(AActor *self, int damagemul)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(mult, 0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT(mult);
|
||||
|
||||
MarinePunch(self, mult);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -345,7 +364,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void P_GunShot2 (AActor *mo, bool accurate, int pitch, const PClass *pufftype)
|
||||
void P_GunShot2 (AActor *mo, bool accurate, int pitch, PClassActor *pufftype)
|
||||
{
|
||||
angle_t angle;
|
||||
int damage;
|
||||
|
@ -369,16 +388,17 @@ void P_GunShot2 (AActor *mo, bool accurate, int pitch, const PClass *pufftype)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
|
||||
{
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_BOOL(accurate);
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(accurate, 0);
|
||||
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->angle, MISSILERANGE),
|
||||
PClass::FindClass(NAME_BulletPuff));
|
||||
PClass::FindActor(NAME_BulletPuff));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -389,19 +409,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int pitch;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
|
||||
A_FaceTarget (self);
|
||||
pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
P_GunShot2 (self, false, pitch, PClass::FindClass(NAME_BulletPuff));
|
||||
P_GunShot2 (self, false, pitch, PClass::FindActor(NAME_BulletPuff));
|
||||
}
|
||||
self->special1 = level.maptime + 27;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -412,6 +435,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->special1 != 0 || self->target == NULL)
|
||||
{
|
||||
self->SetState (self->FindState("SkipAttack"));
|
||||
|
@ -420,6 +445,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
|
|||
{
|
||||
A_FaceTarget (self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -430,10 +456,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int pitch;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
|
||||
A_FaceTarget (self);
|
||||
|
@ -448,6 +476,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
|
|||
NAME_Hitscan, NAME_BulletPuff);
|
||||
}
|
||||
self->special1 = level.maptime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -458,16 +487,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
|
||||
{
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_BOOL(accurate);
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(accurate, 0);
|
||||
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->angle, MISSILERANGE),
|
||||
PClass::FindClass(NAME_BulletPuff));
|
||||
PClass::FindActor(NAME_BulletPuff));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -482,8 +512,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (self->CheckMeleeRange ())
|
||||
{ // If too close, punch it
|
||||
|
@ -492,8 +524,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
|
|||
else
|
||||
{
|
||||
A_FaceTarget (self);
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("Rocket"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("Rocket"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -504,11 +537,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FireRailgun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
CALL_ACTION(A_MonsterRail, self);
|
||||
self->special1 = level.maptime + 50;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -519,12 +555,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireRailgun)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FirePlasma)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("PlasmaBall"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("PlasmaBall"));
|
||||
self->special1 = level.maptime + 20;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -535,8 +574,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FirePlasma)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (self->special1 != 0)
|
||||
{
|
||||
|
@ -549,6 +590,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
|
|||
// Don't interrupt the firing sequence
|
||||
self->PainChance = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -559,13 +601,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_M_FireBFG)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
A_FaceTarget (self);
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("BFGBall"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("BFGBall"));
|
||||
self->special1 = level.maptime + 30;
|
||||
self->PainChance = MARINE_PAIN_CHANCE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -597,11 +642,11 @@ void AScriptedMarine::SetWeapon (EMarineWeapon type)
|
|||
}
|
||||
}
|
||||
|
||||
void AScriptedMarine::SetSprite (const PClass *source)
|
||||
void AScriptedMarine::SetSprite (PClassActor *source)
|
||||
{
|
||||
if (source == NULL || source->ActorInfo == NULL)
|
||||
if (source == NULL)
|
||||
{ // A valid actor class wasn't passed, so use the standard sprite
|
||||
SpriteOverride = sprite = GetClass()->ActorInfo->OwnedStates[0].sprite;
|
||||
SpriteOverride = sprite = GetClass()->OwnedStates[0].sprite;
|
||||
// Copy the standard scaling
|
||||
scaleX = GetDefault()->scaleX;
|
||||
scaleY = GetDefault()->scaleY;
|
||||
|
|
|
@ -13,11 +13,13 @@ 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;
|
||||
return 0;
|
||||
|
||||
if (!self->target
|
||||
|| P_HitFriend (self)
|
||||
|
@ -26,10 +28,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire)
|
|||
{
|
||||
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 (self);
|
||||
A_Chase (stack, self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -259,10 +259,10 @@ void InitActorNumsFromMapinfo()
|
|||
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
const PClass *cls = NULL;
|
||||
PClassActor *cls = NULL;
|
||||
if (pair->Value.classname != NAME_None)
|
||||
{
|
||||
cls = PClass::FindClass(pair->Value.classname);
|
||||
cls = PClass::FindActor(pair->Value.classname);
|
||||
if (cls == NULL)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Script error, \"%s\" line %d:\nUnknown actor class %s\n",
|
||||
|
|
|
@ -439,13 +439,16 @@ CCMD (use)
|
|||
{
|
||||
if (argv.argc() > 1 && who != NULL)
|
||||
{
|
||||
SendItemUse = who->FindInventory (PClass::FindClass (argv[1]));
|
||||
SendItemUse = who->FindInventory(PClass::FindActor(argv[1]));
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (invdrop)
|
||||
{
|
||||
if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel;
|
||||
if (players[consoleplayer].mo)
|
||||
{
|
||||
SendItemDrop = players[consoleplayer].mo->InvSel;
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (weapdrop)
|
||||
|
@ -457,11 +460,11 @@ CCMD (drop)
|
|||
{
|
||||
if (argv.argc() > 1 && who != NULL)
|
||||
{
|
||||
SendItemDrop = who->FindInventory (PClass::FindClass (argv[1]));
|
||||
SendItemDrop = who->FindInventory(PClass::FindActor(argv[1]));
|
||||
}
|
||||
}
|
||||
|
||||
const PClass *GetFlechetteType(AActor *other);
|
||||
PClassActor *GetFlechetteType(AActor *other);
|
||||
|
||||
CCMD (useflechette)
|
||||
{ // Select from one of arti_poisonbag1-3, whichever the player has
|
||||
|
@ -475,7 +478,7 @@ CCMD (useflechette)
|
|||
if (who == NULL)
|
||||
return;
|
||||
|
||||
const PClass *type = GetFlechetteType(who);
|
||||
PClassActor *type = GetFlechetteType(who);
|
||||
if (type != NULL)
|
||||
{
|
||||
AInventory *item;
|
||||
|
@ -502,7 +505,7 @@ CCMD (select)
|
|||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
AInventory *item = who->FindInventory (PClass::FindClass (argv[1]));
|
||||
AInventory *item = who->FindInventory(PClass::FindActor(argv[1]));
|
||||
if (item != NULL)
|
||||
{
|
||||
who->InvSel = item;
|
||||
|
@ -1350,7 +1353,7 @@ void G_PlayerReborn (int player)
|
|||
BYTE currclass;
|
||||
userinfo_t userinfo; // [RH] Save userinfo
|
||||
APlayerPawn *actor;
|
||||
const PClass *cls;
|
||||
PClassPlayerPawn *cls;
|
||||
FString log;
|
||||
DBot *Bot; //Added by MC:
|
||||
|
||||
|
|
|
@ -66,9 +66,11 @@ void AChickenPlayer::MorphPlayerThink ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->CheckMeleeRange())
|
||||
{
|
||||
|
@ -76,6 +78,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
|
|||
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
|
||||
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -86,6 +89,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
int count;
|
||||
AActor *mo;
|
||||
|
@ -107,6 +112,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
|
|||
mo->velz = FRACUNIT + (pr_feathers() << 9);
|
||||
mo->SetState (mo->SpawnState + (pr_feathers()&7));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -132,14 +138,17 @@ void P_UpdateBeak (AActor *self)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP;
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState());
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -161,6 +170,8 @@ void P_PlayPeck (AActor *chicken)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
@ -169,7 +180,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
damage = 1 + (pr_beakatkpl1()&3);
|
||||
|
@ -183,6 +194,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|||
P_PlayPeck (player->mo);
|
||||
player->chickenPeck = 12;
|
||||
player->psprites[ps_weapon].tics -= pr_beakatkpl1() & 7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -193,6 +205,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
@ -201,7 +215,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
damage = pr_beakatkpl2.HitDice (4);
|
||||
|
@ -215,4 +229,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
|||
P_PlayPeck (player->mo);
|
||||
player->chickenPeck = 12;
|
||||
player->psprites[ps_weapon].tics -= pr_beakatkpl2()&3;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,11 @@ static FRandom pr_bluespark ("BlueSpark");
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -40,12 +43,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_Sor1Pain)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Sor1Chase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->special1)
|
||||
{
|
||||
self->special1--;
|
||||
self->tics -= 3;
|
||||
}
|
||||
A_Chase(self);
|
||||
A_Chase(stack, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -58,13 +64,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_Sor1Chase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
fixed_t velz;
|
||||
angle_t angle;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -72,10 +80,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const PClass *fx = PClass::FindClass("SorcererFX1");
|
||||
PClassActor *fx = PClass::FindActor("SorcererFX1");
|
||||
if (self->health > (self->SpawnHealth()/3)*2)
|
||||
{ // Spit one fireball
|
||||
P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx );
|
||||
|
@ -103,6 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -113,6 +122,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
self->flags &= ~MF_SOLID;
|
||||
|
@ -121,6 +132,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
|
|||
mo->SetState (mo->FindState("Rise"));
|
||||
mo->angle = self->angle;
|
||||
mo->CopyFriendliness (self, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -167,6 +179,7 @@ void P_DSparilTeleport (AActor *actor)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
static const int chance[] =
|
||||
{
|
||||
|
@ -183,6 +196,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
|
|||
{
|
||||
P_DSparilTeleport (self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -193,11 +207,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int chance;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NONE);
|
||||
if (self->CheckMeleeRange())
|
||||
|
@ -205,13 +221,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
chance = self->health < self->SpawnHealth()/2 ? 96 : 48;
|
||||
if (pr_s2a() < chance)
|
||||
{ // Wizard spawners
|
||||
|
||||
const PClass *fx = PClass::FindClass("Sorcerer2FX2");
|
||||
PClassActor *fx = PClass::FindActor("Sorcerer2FX2");
|
||||
if (fx)
|
||||
{
|
||||
P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2);
|
||||
|
@ -220,8 +236,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
|
|||
}
|
||||
else
|
||||
{ // Blue bolt
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass("Sorcerer2FX1"));
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("Sorcerer2FX1"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -232,6 +249,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
AActor *mo;
|
||||
|
||||
|
@ -242,6 +261,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
|
|||
mo->vely = pr_bluespark.Random2() << 9;
|
||||
mo->velz = FRACUNIT + (pr_bluespark()<<8);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -252,6 +272,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
|
||||
|
@ -275,6 +297,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
|
|||
Spawn<ATeleportFog> (self->Pos(), ALLOW_REPLACE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -285,8 +308,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->special1 = 7; // Animation loop counter
|
||||
P_Massacre (); // Kill monsters early
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -297,9 +323,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthLoop)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (--self->special1)
|
||||
{ // Need to loop
|
||||
self->SetState (self->FindState("DeathLoop"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,12 +47,15 @@ bool AArtiTomeOfPower::Use (bool pickup)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->AddZ(32*FRACUNIT, false);
|
||||
self->PrevZ = self->Z(); // no interpolation!
|
||||
self->RenderStyle = STYLE_Add;
|
||||
self->alpha = FRACUNIT;
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
|
||||
P_CheckSplash(self, 128<<FRACBITS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
class AArtiTimeBomb : public AInventory
|
||||
|
|
|
@ -21,12 +21,15 @@ static FRandom pr_imp ("ImpExplode");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target || pr_impmsatk() > 64)
|
||||
{
|
||||
self->SetState (self->SeeState);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
A_SkullAttack(self, 12 * FRACUNIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -37,6 +40,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *chunk;
|
||||
|
||||
self->flags &= ~MF_NOGRAVITY;
|
||||
|
@ -54,6 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
|
|||
{ // Extreme death crash
|
||||
self->SetState (self->FindState("XCrash"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -64,8 +70,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->flags &= ~MF_SOLID;
|
||||
self->flags2 |= MF2_FLOORCLIP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -76,9 +85,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@ static FRandom pr_volcimpact ("VolcBallImpact");
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(gootype, 0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT (gootype, AActor) { gootype = PClass::FindActor("PodGoo"); }
|
||||
|
||||
int count;
|
||||
int chance;
|
||||
|
@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
|
|||
chance = pr_podpain ();
|
||||
if (chance < 128)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
for (count = chance > 240 ? 2 : 1; count; count--)
|
||||
{
|
||||
|
@ -63,6 +63,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
|
|||
goo->vely = pr_podpain.Random2() << 9;
|
||||
goo->velz = FRACUNIT/2 + (pr_podpain() << 9);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -73,15 +74,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if ( (mo = self->master))
|
||||
if ( (mo = self->master) )
|
||||
{
|
||||
if (mo->special1 > 0)
|
||||
{
|
||||
mo->special1--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -94,8 +98,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(podtype, 0);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); }
|
||||
|
||||
AActor *mo;
|
||||
fixed_t x;
|
||||
|
@ -103,7 +107,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
|
|||
|
||||
if (self->special1 == MAX_GEN_PODS)
|
||||
{ // Too many generated pods
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
x = self->X();
|
||||
y = self->Y();
|
||||
|
@ -111,14 +115,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
|
|||
if (!P_CheckPosition (mo, x, y))
|
||||
{ // Didn't fit
|
||||
mo->Destroy ();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo->SetState (mo->FindState("Grow"));
|
||||
P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -129,10 +133,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (++self->health > 35)
|
||||
{
|
||||
self->velz += self->velz/2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,7 +151,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->tics = 105 + (pr_volcano() & 127);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -155,6 +165,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
int count;
|
||||
AActor *blast;
|
||||
|
@ -174,6 +186,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
|
|||
S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
|
||||
P_CheckMissileSpawn (blast, self->radius);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -184,6 +197,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
unsigned int i;
|
||||
AActor *tiny;
|
||||
angle_t angle;
|
||||
|
@ -208,5 +223,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
|
|||
tiny->velz = FRACUNIT + (pr_volcimpact() << 9);
|
||||
P_CheckMissileSpawn (tiny, self->radius);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ extern bool P_AutoUseChaosDevice (player_t *player);
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int slope;
|
||||
player_t *player;
|
||||
|
@ -68,20 +70,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACTION_PARAM_START(2);
|
||||
ACTION_PARAM_INT(damage, 0);
|
||||
ACTION_PARAM_CLASS(puff, 1);
|
||||
PARAM_INT (damage);
|
||||
PARAM_CLASS (puff, AActor);
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (puff == NULL)
|
||||
{
|
||||
puff = PClass::FindActor(NAME_BulletPuff); // just to be sure
|
||||
}
|
||||
if (puff == NULL) puff = PClass::FindClass(NAME_BulletPuff); // just to be sure
|
||||
angle = self->angle;
|
||||
angle += pr_sap.Random2() << 18;
|
||||
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
|
||||
|
@ -92,6 +96,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
|
|||
// turn to face target
|
||||
self->angle = self->AngleTo(linetarget);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,20 +108,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle_t pitch = P_BulletSlope(self);
|
||||
damage = 7+(pr_fgw()&7);
|
||||
|
@ -127,6 +134,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
|
|||
}
|
||||
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1");
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -137,6 +145,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
angle_t angle;
|
||||
int damage;
|
||||
|
@ -145,20 +155,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle_t pitch = P_BulletSlope(self);
|
||||
velz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed,
|
||||
finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]);
|
||||
P_SpawnMissileAngle (self, PClass::FindClass("GoldWandFX2"), self->angle-(ANG45/8), velz);
|
||||
P_SpawnMissileAngle (self, PClass::FindClass("GoldWandFX2"), self->angle+(ANG45/8), velz);
|
||||
P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle-(ANG45/8), velz);
|
||||
P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), velz);
|
||||
angle = self->angle-(ANG45/8);
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
|
@ -167,6 +177,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
|
|||
angle += ((ANG45/8)*2)/4;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -177,22 +188,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX1"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle+(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/10));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -203,24 +217,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle-(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle+(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/5));
|
||||
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle+(ANG45/5));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5));
|
||||
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/5));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -231,29 +248,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
int randVal;
|
||||
fixed_t dist;
|
||||
player_t *player;
|
||||
const PClass *pufftype;
|
||||
PClassActor *pufftype;
|
||||
AActor *linetarget;
|
||||
int actualdamage = 0;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(power, 0);
|
||||
PARAM_INT(power);
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT;
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3) * FRACUNIT;
|
||||
|
@ -263,14 +281,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
damage = pr_gatk.HitDice (2);
|
||||
dist = 4*MELEERANGE;
|
||||
angle += pr_gatk.Random2() << 17;
|
||||
pufftype = PClass::FindClass("GauntletPuff2");
|
||||
pufftype = PClass::FindActor("GauntletPuff2");
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = pr_gatk.HitDice (2);
|
||||
dist = MELEERANGE+1;
|
||||
angle += pr_gatk.Random2() << 18;
|
||||
pufftype = PClass::FindClass("GauntletPuff1");
|
||||
pufftype = PClass::FindActor("GauntletPuff1");
|
||||
}
|
||||
slope = P_AimLineAttack (self, angle, dist, &linetarget);
|
||||
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);
|
||||
|
@ -281,7 +299,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
player->extralight = !player->extralight;
|
||||
}
|
||||
S_Sound (self, CHAN_AUTO, "weapons/gauntletson", 1, ATTN_NORM);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
randVal = pr_gatk();
|
||||
if (randVal < 64)
|
||||
|
@ -322,6 +340,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
self->angle += ANG90/20;
|
||||
}
|
||||
self->flags |= MF_JUSTATTACKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- Mace -----------------------------------------------------------------
|
||||
|
@ -404,33 +423,36 @@ void FireMacePL1B (AActor *actor)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *ball;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pr_maceatk() < 28)
|
||||
{
|
||||
FireMacePL1B (self);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT;
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT;
|
||||
ball = P_SpawnPlayerMissile (self, PClass::FindClass("MaceFX1"),
|
||||
ball = P_SpawnPlayerMissile (self, PClass::FindActor("MaceFX1"),
|
||||
self->angle+(((pr_maceatk()&7)-4)<<24));
|
||||
if (ball)
|
||||
{
|
||||
ball->special1 = 16; // tics till dropoff
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -441,14 +463,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->special1 == 0)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
self->special1 -= 4;
|
||||
if (self->special1 > 0)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
self->special1 = 0;
|
||||
self->flags &= ~MF_NOGRAVITY;
|
||||
|
@ -467,6 +491,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
|
|||
self->vely = (int)(self->vely * velscale);
|
||||
#endif
|
||||
self->velz -= self->velz >> 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -477,6 +502,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE))
|
||||
{ // Bounce
|
||||
self->health = MAGIC_JUNK;
|
||||
|
@ -492,6 +519,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
|
|||
self->gravity = FRACUNIT;
|
||||
S_Sound (self, CHAN_BODY, "weapons/macehit", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -502,13 +530,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *tiny;
|
||||
angle_t angle;
|
||||
|
||||
if ((self->Z() <= self->floorz) && P_HitFloor (self))
|
||||
{ // Landed in some sort of liquid
|
||||
self->Destroy ();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->flags & MF_INBOUNCE)
|
||||
{
|
||||
|
@ -549,6 +579,7 @@ boom:
|
|||
self->BounceFlags = BOUNCE_None;
|
||||
self->gravity = FRACUNIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -559,20 +590,22 @@ boom:
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &linetarget);
|
||||
if (mo)
|
||||
|
@ -587,6 +620,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
|
|||
}
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/maceshoot", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -597,6 +631,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
AActor *target;
|
||||
angle_t angle = 0;
|
||||
|
@ -606,7 +642,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
|
|||
if ((self->Z() <= self->floorz) && P_HitFloor (self))
|
||||
{ // Landed in some sort of liquid
|
||||
self->Destroy ();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->flags & MF_INBOUNCE)
|
||||
{
|
||||
|
@ -664,6 +700,7 @@ boom:
|
|||
self->gravity = FRACUNIT;
|
||||
S_Sound (self, CHAN_BODY, "weapons/maceexplode", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -739,20 +776,22 @@ int ARipper::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle_t pitch = P_BulletSlope(self);
|
||||
damage = pr_fb1.HitDice (4);
|
||||
|
@ -763,6 +802,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
|
|||
}
|
||||
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff");
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -773,6 +813,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
unsigned int i;
|
||||
angle_t angle;
|
||||
AActor *ripper;
|
||||
|
@ -788,6 +830,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
|
|||
ripper->vely = FixedMul (ripper->Speed, finesine[angle]);
|
||||
P_CheckMissileSpawn (ripper, self->radius);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- Skull rod ------------------------------------------------------------
|
||||
|
@ -860,26 +903,29 @@ void ARainTracker::Serialize (FArchive &arc)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo = P_SpawnPlayerMissile (self, PClass::FindClass("HornRodFX1"));
|
||||
mo = P_SpawnPlayerMissile (self, PClass::FindActor("HornRodFX1"));
|
||||
// Randomize the first frame
|
||||
if (mo && pr_fsr1() > 128)
|
||||
{
|
||||
mo->SetState (mo->state->GetNextState());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -893,19 +939,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
AActor *MissileActor;
|
||||
AActor *linetarget;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &linetarget, &MissileActor);
|
||||
// Use MissileActor instead of the return value from
|
||||
|
@ -920,6 +968,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2)
|
|||
}
|
||||
S_Sound (MissileActor, CHAN_WEAPON, "weapons/hornrodpowshoot", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -930,11 +979,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
ARainTracker *tracker;
|
||||
|
||||
if (self->target == NULL || self->target->health <= 0)
|
||||
{ // Shooter is dead or nonexistant
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tracker = self->target->FindInventory<ARainTracker> ();
|
||||
|
@ -977,6 +1028,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
|
|||
tracker->Rain1 = self;
|
||||
}
|
||||
self->special1 = S_FindSound ("misc/rain");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -987,6 +1039,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
ARainTracker *tracker;
|
||||
|
||||
|
@ -996,7 +1050,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
|||
if (self->target == NULL)
|
||||
{ // Player left the game
|
||||
self->Destroy ();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
tracker = self->target->FindInventory<ARainTracker> ();
|
||||
if (tracker != NULL)
|
||||
|
@ -1011,18 +1065,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
|||
}
|
||||
}
|
||||
self->Destroy ();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (pr_storm() < 25)
|
||||
{ // Fudge rain frequency
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
fixedvec2 pos = self->Vec2Offset(
|
||||
((pr_storm()&127) - 64) * FRACUNIT,
|
||||
((pr_storm()&127) - 64) * FRACUNIT);
|
||||
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
|
||||
// We used bouncecount to store the 3D floor index in A_HideInCeiling
|
||||
if (!mo) return;
|
||||
if (!mo) return 0;
|
||||
fixed_t newz;
|
||||
if (self->bouncecount >= 0
|
||||
&& (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
|
||||
|
@ -1043,6 +1097,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
|||
{
|
||||
S_Sound (self, CHAN_BODY|CHAN_LOOP, self->special1, 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1053,6 +1108,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
if (self->Z() > self->floorz)
|
||||
{
|
||||
self->SetState (self->FindState("NotFloor"));
|
||||
|
@ -1061,6 +1117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
|
|||
{
|
||||
P_HitFloor (self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1071,6 +1128,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// We use bouncecount to store the 3D floor index
|
||||
fixed_t foo;
|
||||
for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++)
|
||||
|
@ -1082,11 +1141,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling)
|
|||
{
|
||||
self->SetZ(foo + 4*FRACUNIT, false);
|
||||
self->bouncecount = i;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
self->bouncecount = -1;
|
||||
self->SetZ(self->ceilingz + 4*FRACUNIT, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- Phoenix Rod ----------------------------------------------------------
|
||||
|
@ -1170,25 +1230,28 @@ int APhoenixFX2::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1));
|
||||
angle = self->angle + ANG180;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
self->velx += FixedMul (4*FRACUNIT, finecosine[angle]);
|
||||
self->vely += FixedMul (4*FRACUNIT, finesine[angle]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1199,6 +1262,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *puff;
|
||||
angle_t angle;
|
||||
|
||||
|
@ -1216,6 +1281,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
|
|||
puff->velx = FixedMul (FRACUNIT*13/10, finecosine[angle]);
|
||||
puff->vely = FixedMul (FRACUNIT*13/10, finesine[angle]);
|
||||
puff->velz = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1226,6 +1292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL)
|
||||
{
|
||||
APhoenixRod *flamethrower = static_cast<APhoenixRod *> (self->player->ReadyWeapon);
|
||||
|
@ -1234,6 +1302,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
|
|||
flamethrower->FlameCount = FLAME_THROWER_TICS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1246,6 +1315,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
angle_t angle;
|
||||
|
||||
|
@ -1256,7 +1327,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
soundid = "weapons/phoenixpowshoot";
|
||||
|
@ -1267,7 +1338,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
P_SetPsprite (player, ps_weapon, flamethrower->FindState("Powerdown"));
|
||||
player->refire = 0;
|
||||
S_StopSound (self, CHAN_WEAPON);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle = self->angle;
|
||||
|
||||
|
@ -1288,6 +1359,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM);
|
||||
}
|
||||
P_CheckMissileSpawn (mo, self->radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1298,19 +1370,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ShutdownPhoenixPL2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_StopSound (self, CHAN_WEAPON);
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1321,7 +1396,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShutdownPhoenixPL2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->velz += FRACUNIT*3/2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1332,6 +1410,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->velz += FRACUNIT*18/10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
AActor *fire;
|
||||
AActor *baseFire;
|
||||
|
@ -81,7 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
target = self->target;
|
||||
if (target == NULL)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange ())
|
||||
|
@ -89,18 +91,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
dist = self->AproxDistance (target) > 8*64*FRACUNIT;
|
||||
randAttack = pr_atk ();
|
||||
if (randAttack < atkResolve1[dist])
|
||||
{ // Ice ball
|
||||
P_SpawnMissile (self, target, PClass::FindClass("HeadFX1"));
|
||||
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::FindClass("HeadFX3"));
|
||||
baseFire = P_SpawnMissile (self, target, PClass::FindActor("HeadFX3"));
|
||||
if (baseFire != NULL)
|
||||
{
|
||||
baseFire->SetState (baseFire->FindState("NoGrow"));
|
||||
|
@ -116,7 +118,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
fire->velx = baseFire->velx;
|
||||
fire->vely = baseFire->vely;
|
||||
fire->velz = baseFire->velz;
|
||||
fire->Damage = 0;
|
||||
fire->Damage = NULL;
|
||||
fire->health = (i+1) * 2;
|
||||
P_CheckMissileSpawn (fire, self->radius);
|
||||
}
|
||||
|
@ -135,6 +137,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -145,13 +148,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->health -= 3;
|
||||
if (self->health < 0)
|
||||
{
|
||||
self->velx = self->vely = self->velz = 0;
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
self->flags &= ~MF_MISSILE;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if ((self->special2 -= 3) < 0)
|
||||
{
|
||||
|
@ -160,9 +165,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
|
|||
}
|
||||
if (self->tracer && self->tracer->flags&MF_SHADOW)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SeekerMissile (self, ANGLE_1*10, ANGLE_1*30);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -173,6 +179,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
unsigned int i;
|
||||
angle_t angle;
|
||||
AActor *shard;
|
||||
|
@ -189,6 +197,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
|
|||
shard->velz = -FRACUNIT*6/10;
|
||||
P_CheckMissileSpawn (shard, self->radius);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -199,6 +208,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->health--;
|
||||
self->AddZ(9*FRACUNIT);
|
||||
if (self->health == 0)
|
||||
|
@ -206,5 +217,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
|
|||
self->Damage = self->GetDefault()->Damage;
|
||||
self->SetState (self->FindState("NoGrow"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ static FRandom pr_knightatk ("KnightAttack");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
fixed_t xo = (pr_dripblood.Random2() << 11);
|
||||
|
@ -29,6 +31,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
|
|||
mo->velx = pr_dripblood.Random2 () << 10;
|
||||
mo->vely = pr_dripblood.Random2 () << 10;
|
||||
mo->gravity = FRACUNIT/8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -39,9 +42,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->CheckMeleeRange ())
|
||||
{
|
||||
|
@ -49,16 +54,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
|
|||
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;
|
||||
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*FRACUNIT, self->target, PClass::FindClass("RedAxe"));
|
||||
return;
|
||||
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("RedAxe"));
|
||||
return 0;
|
||||
}
|
||||
// Green axe
|
||||
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindClass("KnightAxe"));
|
||||
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("KnightAxe"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,11 @@ static FRandom pr_wizatk3 ("WizAtk3");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_GhostOff)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->RenderStyle = STYLE_Normal;
|
||||
self->flags3 &= ~MF3_GHOST;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -32,8 +35,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_GhostOff)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_FaceTarget (self);
|
||||
CALL_ACTION(A_GhostOff, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -44,10 +50,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -58,12 +67,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
CALL_ACTION(A_GhostOff, self);
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
||||
if (self->CheckMeleeRange())
|
||||
|
@ -71,13 +82,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
const PClass *fx = PClass::FindClass("WizardFX1");
|
||||
PClassActor *fx = PClass::FindActor("WizardFX1");
|
||||
mo = P_SpawnMissile (self, self->target, fx);
|
||||
if (mo != NULL)
|
||||
{
|
||||
P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->velz);
|
||||
P_SpawnMissileAngle(self, fx, mo->angle+(ANG45/8), mo->velz);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,23 +27,28 @@ static FRandom pr_batmove ("BatMove");
|
|||
|
||||
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;
|
||||
angle_t angle;
|
||||
|
||||
// Countdown until next spawn
|
||||
if (self->special1-- > 0) return;
|
||||
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->angle + (((pr_batspawn()%delta)-(delta>>1))<<24);
|
||||
mo = P_SpawnMissileAngle (self, PClass::FindClass ("Bat"), angle, 0);
|
||||
mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0);
|
||||
if (mo)
|
||||
{
|
||||
mo->args[0] = pr_batspawn()&63; // floatbob index
|
||||
|
@ -51,11 +56,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
|
|||
mo->special2 = self->args[3]<<3; // Set lifetime
|
||||
mo->target = self;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t newangle;
|
||||
|
||||
if (self->special2 < 0)
|
||||
|
@ -86,4 +94,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
|
|||
// Handle Z movement
|
||||
self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]);
|
||||
self->args[0] = (self->args[0]+3)&63;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@ static FRandom pr_pain ("BishopPainBlur");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
|
||||
if (self->CheckMeleeRange())
|
||||
|
@ -34,9 +36,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
|
|||
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;
|
||||
return 0;
|
||||
}
|
||||
self->special1 = (pr_atk() & 3) + 5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -48,20 +51,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if (!self->target || !self->special1)
|
||||
{
|
||||
self->special1 = 0;
|
||||
self->SetState (self->SeeState);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo = P_SpawnMissile (self, self->target, PClass::FindClass("BishopFX"));
|
||||
mo = P_SpawnMissile (self, self->target, PClass::FindActor("BishopFX"));
|
||||
if (mo != NULL)
|
||||
{
|
||||
mo->tracer = self->target;
|
||||
}
|
||||
self->special1--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -72,7 +78,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -83,14 +92,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopDecide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (pr_decide() < 220)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->SetState (self->FindState ("Blur"));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -101,6 +113,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDecide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
|
||||
if (pr_doblur() < 120)
|
||||
{
|
||||
|
@ -115,6 +129,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
|
|||
P_ThrustMobj (self, self->angle, 11*FRACUNIT);
|
||||
}
|
||||
S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -125,6 +140,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if (!--self->special1)
|
||||
|
@ -145,6 +162,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
|
|||
{
|
||||
mo->angle = self->angle;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -155,10 +173,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4;
|
||||
self->special2 = (self->special2 + 4) & 63;
|
||||
newz += finesine[self->special2 << BOBTOFINESHIFT] * 4;
|
||||
self->SetZ(newz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -169,6 +190,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE);
|
||||
|
@ -176,6 +199,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
|
|||
{
|
||||
mo->velz = FRACUNIT/2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -186,12 +210,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if (pr_pain() < 64)
|
||||
{
|
||||
self->SetState (self->FindState ("Blur"));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
fixed_t xo = (pr_pain.Random2() << 12);
|
||||
fixed_t yo = (pr_pain.Random2() << 12);
|
||||
|
@ -201,4 +227,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
|
|||
{
|
||||
mo->angle = self->angle;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor * Owner, const PClass * blasteffect, bool dontdamage)
|
||||
void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage)
|
||||
{
|
||||
angle_t angle,ang;
|
||||
AActor *mo;
|
||||
|
@ -97,13 +97,13 @@ enum
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
|
||||
{
|
||||
ACTION_PARAM_START(6);
|
||||
ACTION_PARAM_INT (blastflags, 0);
|
||||
ACTION_PARAM_FIXED(strength, 1);
|
||||
ACTION_PARAM_FIXED(radius, 2);
|
||||
ACTION_PARAM_FIXED(speed, 3);
|
||||
ACTION_PARAM_CLASS(blasteffect, 4);
|
||||
ACTION_PARAM_SOUND(blastsound, 5);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT (blastflags) { blastflags = 0; }
|
||||
PARAM_INT_OPT (strength) { strength = 255; }
|
||||
PARAM_INT_OPT (radius) { radius = 255; }
|
||||
PARAM_FIXED_OPT (speed) { speed = 20; }
|
||||
PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); }
|
||||
PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; }
|
||||
|
||||
AActor *mo;
|
||||
TThinkerIterator<AActor> iterator;
|
||||
|
@ -111,15 +111,19 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
|
|||
|
||||
if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
AWeapon * weapon = self->player->ReadyWeapon;
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && !weapon->DepleteAmmo(weapon->bAltFire))
|
||||
return;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_AUTO, blastsound, 1, ATTN_NORM);
|
||||
|
||||
if (!(blastflags & BF_DONTWARN)) P_NoiseAlert (self, self);
|
||||
|
||||
if (!(blastflags & BF_DONTWARN))
|
||||
{
|
||||
P_NoiseAlert (self, self);
|
||||
}
|
||||
while ( (mo = iterator.Next ()) )
|
||||
{
|
||||
if ((mo == self) || ((mo->flags2 & MF2_BOSS) && !(blastflags & BF_AFFECTBOSSES))
|
||||
|
@ -149,4 +153,5 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
|
|||
}
|
||||
BlastActor (mo, strength, speed, self, blasteffect, !!(blastflags & BF_NOIMPACTDAMAGE));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ static FRandom pr_centaurdefend ("CentaurDefend");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CentaurDefend)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_FaceTarget (self);
|
||||
if (self->CheckMeleeRange() && pr_centaurdefend() < 32)
|
||||
{
|
||||
|
@ -24,4 +26,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CentaurDefend)
|
|||
self->flags2&=~(MF2_REFLECTIVE|MF2_INVULNERABLE);
|
||||
self->SetState (self->MeleeState);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -69,20 +69,23 @@ void ACFlameMissile::Effect ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CFlameAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACFlameMissile));
|
||||
S_Sound (self, CHAN_WEAPON, "ClericFlameFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -93,11 +96,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->renderflags &= ~RF_INVISIBLE;
|
||||
self->velx = 0;
|
||||
self->vely = 0;
|
||||
self->velz = 0;
|
||||
S_Sound (self, CHAN_BODY, "ClericFlameExplode", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -108,6 +114,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
int an, an90;
|
||||
fixed_t dist;
|
||||
|
@ -150,6 +158,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
|
|||
}
|
||||
self->SetState (self->SpawnState);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -160,10 +169,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int an;
|
||||
|
||||
an = (self->angle+ANG90)>>ANGLETOFINESHIFT;
|
||||
self->velx = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]);
|
||||
self->vely = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]);
|
||||
self->angle += ANG90/15;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,8 @@ bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int j;
|
||||
int i;
|
||||
AActor *mo;
|
||||
|
@ -175,6 +177,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
|
|||
}
|
||||
SpawnSpiritTail (mo);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -207,24 +210,30 @@ void SpawnSpiritTail (AActor *spirit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon);
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &linetarget);
|
||||
if (missile != NULL)
|
||||
{
|
||||
missile->tracer = linetarget;
|
||||
}
|
||||
AActor * missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindClass ("HolyMissile"), self->angle, &linetarget);
|
||||
if (missile != NULL) missile->tracer = linetarget;
|
||||
|
||||
weapon->CHolyCount = 3;
|
||||
S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -235,6 +244,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL)
|
||||
{
|
||||
ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon);
|
||||
|
@ -243,6 +254,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette)
|
|||
weapon->CHolyCount--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -316,6 +328,8 @@ static void CHolyTailRemove (AActor *actor)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *parent;
|
||||
|
||||
parent = self->target;
|
||||
|
@ -323,7 +337,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
|
|||
if (parent == NULL || parent->health <= 0) // better check for health than current state - it's safer!
|
||||
{ // Ghost removed, so remove all tail parts
|
||||
CHolyTailRemove (self);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -335,6 +349,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
|
|||
}
|
||||
CHolyTailFollow (self, 10*FRACUNIT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -471,6 +486,8 @@ void CHolyWeave (AActor *actor, FRandom &pr_random)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->health--;
|
||||
if (self->health <= 0)
|
||||
{
|
||||
|
@ -479,7 +496,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
|
|||
self->velz = 0;
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
self->tics -= pr_holyseek()&3;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->tracer)
|
||||
{
|
||||
|
@ -491,6 +508,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
|
|||
}
|
||||
}
|
||||
CHolyWeave (self, pr_holyweave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -501,6 +519,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
CALL_ACTION(A_CHolySeek, self);
|
||||
if (pr_checkscream() < 20)
|
||||
{
|
||||
|
@ -510,6 +530,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
|
|||
{
|
||||
CHolyFindTarget(self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -521,10 +542,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ClericAttack)
|
||||
{
|
||||
if (!self->target) return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor * missile = P_SpawnMissileZ (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindClass ("HolyMissile"));
|
||||
if (!self->target) return 0;
|
||||
|
||||
AActor * missile = P_SpawnMissileZ (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor ("HolyMissile"));
|
||||
if (missile != NULL) missile->tracer = NULL; // No initial target
|
||||
S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ static FRandom pr_maceatk ("CMaceAttack");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
@ -26,9 +28,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PClassActor *hammertime = PClass::FindActor("HammerPuff");
|
||||
|
||||
damage = 25+(pr_maceatk()&15);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
|
@ -36,7 +40,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
|
@ -47,7 +51,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
|
||||
P_LineAttack (player->mo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle (player->mo, linetarget);
|
||||
|
@ -60,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
|
|||
|
||||
angle = player->mo->angle;
|
||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"));
|
||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime);
|
||||
macedone:
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ int ACStaffMissile::DoSpecialDamage (AActor *target, int damage, FName damagetyp
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
APlayerPawn *pmo;
|
||||
int damage;
|
||||
int newLife, max;
|
||||
|
@ -54,45 +56,47 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
int i;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
PClassActor *puff;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
|
||||
pmo = player->mo;
|
||||
damage = 20+(pr_staffcheck()&15);
|
||||
max = pmo->GetMaxHealth();
|
||||
puff = PClass::FindActor("CStaffPuff");
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
angle = pmo->angle+i*(ANG45/16);
|
||||
slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
pmo->angle = pmo->AngleTo(linetarget);
|
||||
if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER)
|
||||
if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER)
|
||||
&& (!(linetarget->flags2&(MF2_DORMANT|MF2_INVULNERABLE))))
|
||||
{
|
||||
newLife = player->health+(damage>>3);
|
||||
newLife = newLife > max ? max : newLife;
|
||||
if (newLife > player->health)
|
||||
{
|
||||
newLife = player->health+(damage>>3);
|
||||
newLife = newLife > max ? max : newLife;
|
||||
if (newLife > player->health)
|
||||
{
|
||||
pmo->health = player->health = newLife;
|
||||
}
|
||||
pmo->health = player->health = newLife;
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
FState * newstate = weapon->FindState("Drain");
|
||||
if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate);
|
||||
}
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||
}
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -100,17 +104,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
{
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
pmo->angle = pmo->AngleTo(linetarget);
|
||||
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
|
||||
{
|
||||
newLife = player->health+(damage>>4);
|
||||
newLife = newLife > max ? max : newLife;
|
||||
pmo->health = player->health = newLife;
|
||||
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
|
||||
}
|
||||
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
|
||||
{
|
||||
newLife = player->health+(damage>>4);
|
||||
newLife = newLife > max ? max : newLife;
|
||||
pmo->health = player->health = newLife;
|
||||
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||
|
@ -119,6 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -129,19 +134,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15));
|
||||
if (mo)
|
||||
|
@ -154,6 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
|
|||
mo->WeaveIndexXY = 0;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -164,7 +172,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_Weave(self, 3, 0, FRACUNIT, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -175,7 +186,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CStaffInitBlink)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->weaponspecial = (pr_blink()>>1)+20;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -186,6 +200,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffInitBlink)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player && self->player->ReadyWeapon)
|
||||
{
|
||||
if (!--self->weaponspecial)
|
||||
|
@ -198,4 +214,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink)
|
|||
DoReadyWeapon(self);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
|
|||
}
|
||||
else if (pr_dragonseek() < 128 && P_CheckMissileRange(actor))
|
||||
{
|
||||
P_SpawnMissile(actor, target, PClass::FindClass ("DragonFireball"));
|
||||
P_SpawnMissile(actor, target, PClass::FindActor("DragonFireball"));
|
||||
S_Sound (actor, CHAN_WEAPON, actor->AttackSound, 1, ATTN_NORM);
|
||||
}
|
||||
actor->target = oldTarget;
|
||||
|
@ -155,6 +155,8 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
FActorIterator iterator (self->tid);
|
||||
|
||||
do
|
||||
|
@ -163,10 +165,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
|
|||
if (self->tracer == NULL)
|
||||
{
|
||||
self->SetState (self->SpawnState);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
} while (self->tracer == self);
|
||||
self->RemoveFromHash ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -177,6 +180,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
|
||||
DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1);
|
||||
|
@ -185,7 +190,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
|
|||
if(!(self->target->flags&MF_SHOOTABLE))
|
||||
{ // target died
|
||||
self->target = NULL;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle = self->AngleTo(self->target);
|
||||
if (absangle(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange())
|
||||
|
@ -205,6 +210,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
|
|||
{
|
||||
P_LookForPlayers (self, true, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -215,6 +221,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
CALL_ACTION(A_DragonFlight, self);
|
||||
if (pr_dragonflap() < 240)
|
||||
{
|
||||
|
@ -224,6 +232,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
|
|||
{
|
||||
self->PlayActiveSound ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -234,7 +243,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonAttack)
|
||||
{
|
||||
P_SpawnMissile (self, self->target, PClass::FindClass ("DragonFireball"));
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
P_SpawnMissile (self, self->target, PClass::FindActor("DragonFireball"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -245,6 +257,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int i;
|
||||
int delay;
|
||||
|
@ -262,7 +276,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
|
|||
mo->tics = delay+(pr_dragonfx2()&3)*i*2;
|
||||
mo->target = self->target;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -273,11 +288,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonPain)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
CALL_ACTION(A_Pain, self);
|
||||
if (!self->tracer)
|
||||
{ // no destination spot yet
|
||||
self->SetState (self->SeeState);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -288,8 +306,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonPain)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DragonCheckCrash)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->Z() <= self->floorz)
|
||||
{
|
||||
self->SetState (self->FindState ("Crash"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,11 +68,13 @@ FState *AFWeapAxe::GetAtkState (bool hold)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
|
@ -82,6 +84,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
|
|||
{
|
||||
DoReadyWeapon(self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -92,11 +95,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount <= 0)
|
||||
{
|
||||
|
@ -106,6 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
|
|||
{
|
||||
DoReadyWeapon(self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -116,11 +122,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
|
@ -130,6 +138,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
|
|||
{
|
||||
CALL_ACTION(A_Raise, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -140,11 +149,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount <= 0)
|
||||
{
|
||||
|
@ -154,6 +165,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
|
|||
{
|
||||
CALL_ACTION(A_Raise, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -164,16 +176,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -184,6 +199,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
fixed_t power;
|
||||
int damage;
|
||||
|
@ -192,12 +209,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
|||
int useMana;
|
||||
player_t *player;
|
||||
AWeapon *weapon;
|
||||
const PClass *pufftype;
|
||||
PClassActor *pufftype;
|
||||
AActor *linetarget;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AActor *pmo=player->mo;
|
||||
|
||||
|
@ -209,12 +226,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
|||
{
|
||||
damage <<= 1;
|
||||
power = 6*FRACUNIT;
|
||||
pufftype = PClass::FindClass ("AxePuffGlow");
|
||||
pufftype = PClass::FindActor ("AxePuffGlow");
|
||||
useMana = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pufftype = PClass::FindClass ("AxePuff");
|
||||
pufftype = PClass::FindActor ("AxePuff");
|
||||
useMana = 0;
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
|
@ -275,6 +292,6 @@ axedone:
|
|||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget);
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
fixed_t power;
|
||||
|
@ -34,28 +36,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
|||
int i;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
PClassActor *hammertime;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AActor *pmo=player->mo;
|
||||
|
||||
damage = 60+(pr_hammeratk()&63);
|
||||
power = 10*FRACUNIT;
|
||||
hammertime = PClass::FindActor("HammerPuff");
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
angle = pmo->angle + i*(ANG45/32);
|
||||
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||
if (linetarget)
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj (linetarget, angle, power);
|
||||
P_ThrustMobj(linetarget, angle, power);
|
||||
}
|
||||
pmo->weaponspecial = false; // Don't throw a hammer
|
||||
goto hammerdone;
|
||||
|
@ -63,13 +67,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
|||
}
|
||||
angle = pmo->angle-i*(ANG45/32);
|
||||
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||
if(linetarget)
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
|
||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
AdjustPlayerAngle(pmo, linetarget);
|
||||
if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
|
||||
if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player)
|
||||
{
|
||||
P_ThrustMobj(linetarget, angle, power);
|
||||
}
|
||||
|
@ -81,7 +85,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
|||
// didn't find any targets in meleerange, so set to throw out a hammer
|
||||
angle = pmo->angle;
|
||||
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||
if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true) != NULL)
|
||||
if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL)
|
||||
{
|
||||
pmo->weaponspecial = false;
|
||||
}
|
||||
|
@ -97,7 +101,7 @@ hammerdone:
|
|||
{
|
||||
pmo->weaponspecial = false;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -108,27 +112,30 @@ hammerdone:
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FHammerThrow)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->mo->weaponspecial)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, false))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mo = P_SpawnPlayerMissile (player->mo, PClass::FindClass ("HammerMissile"));
|
||||
mo = P_SpawnPlayerMissile (player->mo, PClass::FindActor("HammerMissile"));
|
||||
if (mo)
|
||||
{
|
||||
mo->special1 = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ void AdjustPlayerAngle (AActor *pmo, AActor *linetarget)
|
|||
|
||||
static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
|
||||
{
|
||||
const PClass *pufftype;
|
||||
PClassActor *pufftype;
|
||||
AActor *linetarget;
|
||||
int slope;
|
||||
|
||||
|
@ -70,11 +70,11 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
|
|||
{
|
||||
damage <<= 1;
|
||||
power *= 3;
|
||||
pufftype = PClass::FindClass ("HammerPuff");
|
||||
pufftype = PClass::FindActor("HammerPuff");
|
||||
}
|
||||
else
|
||||
{
|
||||
pufftype = PClass::FindClass ("PunchPuff");
|
||||
pufftype = PClass::FindActor("PunchPuff");
|
||||
}
|
||||
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
|
||||
if (linetarget != NULL)
|
||||
|
@ -99,6 +99,8 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int damage;
|
||||
fixed_t power;
|
||||
int i;
|
||||
|
@ -106,7 +108,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
APlayerPawn *pmo = player->mo;
|
||||
|
||||
|
@ -120,10 +122,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
if (pmo->weaponspecial >= 3)
|
||||
{
|
||||
pmo->weaponspecial = 0;
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Fire2"));
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState("Fire2"));
|
||||
S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM);
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// didn't find any creatures, so try to strike any walls
|
||||
|
@ -131,5 +133,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
|
||||
AActor *linetarget;
|
||||
int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE, &linetarget);
|
||||
P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindClass("PunchPuff"), true);
|
||||
P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@ static FRandom pr_fswordflame ("FSwordFlame");
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
|
||||
{
|
||||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_CLASS(p1, 0);
|
||||
ACTION_PARAM_CLASS(p2, 1);
|
||||
ACTION_PARAM_CLASS(p3, 2);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS(p1, AActor);
|
||||
PARAM_CLASS(p2, AActor);
|
||||
PARAM_CLASS(p3, AActor);
|
||||
|
||||
for (int i = 0, j = 0, fineang = 0; i < 3; ++i)
|
||||
{
|
||||
const PClass *cls = j==0? p1 : j==1? p2 : p3;
|
||||
PClassActor *cls = j == 0 ? p1 : j == 1 ? p2 : p3;
|
||||
if (cls)
|
||||
{
|
||||
AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE);
|
||||
|
@ -48,6 +48,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,17 +81,19 @@ int AFSwordMissile::DoSpecialDamage(AActor *victim, int damage, FName damagetype
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/4);
|
||||
P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/8);
|
||||
|
@ -98,6 +101,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
|
|||
P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/8);
|
||||
P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/4);
|
||||
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -108,6 +112,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 1+(pr_fswordflame()&3); i; i--)
|
||||
|
@ -117,6 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
|
|||
fixed_t zo = ((pr_fswordflame() - 128) << 11);
|
||||
Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -127,7 +134,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack)
|
||||
{
|
||||
if (!self->target) return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target) return 0;
|
||||
|
||||
angle_t angle = self->angle;
|
||||
|
||||
|
@ -137,5 +146,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack)
|
|||
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/8, 0);
|
||||
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0);
|
||||
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,25 +32,25 @@ static FRandom pr_firedemonsplotch ("FiredSplotch");
|
|||
void A_FiredSpawnRock (AActor *actor)
|
||||
{
|
||||
AActor *mo;
|
||||
const PClass *rtype;
|
||||
PClassActor *rtype;
|
||||
|
||||
switch (pr_firedemonrock() % 5)
|
||||
{
|
||||
case 0:
|
||||
rtype = PClass::FindClass ("FireDemonRock1");
|
||||
rtype = PClass::FindActor("FireDemonRock1");
|
||||
break;
|
||||
case 1:
|
||||
rtype = PClass::FindClass ("FireDemonRock2");
|
||||
rtype = PClass::FindActor("FireDemonRock2");
|
||||
break;
|
||||
case 2:
|
||||
rtype = PClass::FindClass ("FireDemonRock3");
|
||||
rtype = PClass::FindActor("FireDemonRock3");
|
||||
break;
|
||||
case 3:
|
||||
rtype = PClass::FindClass ("FireDemonRock4");
|
||||
rtype = PClass::FindActor("FireDemonRock4");
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
rtype = PClass::FindClass ("FireDemonRock5");
|
||||
rtype = PClass::FindActor("FireDemonRock5");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -80,11 +80,14 @@ void A_FiredSpawnRock (AActor *actor)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_FiredSpawnRock (self);
|
||||
A_FiredSpawnRock (self);
|
||||
A_FiredSpawnRock (self);
|
||||
A_FiredSpawnRock (self);
|
||||
A_FiredSpawnRock (self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -95,11 +98,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// give some more velocity (x,y,&z)
|
||||
self->SetZ(self->floorz + FRACUNIT);
|
||||
self->velz = (2*FRACUNIT) + (pr_smbounce() << 10);
|
||||
self->velx = pr_smbounce()%3<<FRACBITS;
|
||||
self->vely = pr_smbounce()%3<<FRACBITS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -110,10 +116,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
return;
|
||||
AActor *mo = P_SpawnMissile (self, self->target, PClass::FindClass ("FireDemonMissile"));
|
||||
return 0;
|
||||
AActor *mo = P_SpawnMissile (self, self->target, PClass::FindActor("FireDemonMissile"));
|
||||
if (mo) S_Sound (self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -124,6 +133,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int weaveindex = self->special1;
|
||||
AActor *target = self->target;
|
||||
angle_t ang;
|
||||
|
@ -145,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
|||
if(!self->target || !(self->target->flags&MF_SHOOTABLE))
|
||||
{ // Invalid target
|
||||
P_LookForPlayers (self,true, NULL);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Strafe
|
||||
|
@ -193,7 +204,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
|||
{
|
||||
self->SetState (self->MissileState);
|
||||
self->flags |= MF_JUSTATTACKED;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -206,6 +217,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
|||
{
|
||||
self->PlayActiveSound ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -216,6 +228,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE);
|
||||
|
@ -232,4 +246,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
|
|||
mo->vely = (pr_firedemonsplotch() - 128) << 11;
|
||||
mo->velz = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,15 +24,6 @@ DECLARE_ACTION(A_CheckThrowBomb)
|
|||
|
||||
// Poison Bag Artifact (Flechette) ------------------------------------------
|
||||
|
||||
class AArtiPoisonBag : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AArtiPoisonBag, AInventory)
|
||||
public:
|
||||
bool HandlePickup (AInventory *item);
|
||||
AInventory *CreateCopy (AActor *other);
|
||||
void BeginPlay ();
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS (AArtiPoisonBag)
|
||||
|
||||
// Poison Bag 1 (The Cleric's) ----------------------------------------------
|
||||
|
@ -155,10 +146,10 @@ IMPLEMENT_CLASS (AArtiPoisonBagGiver)
|
|||
|
||||
bool AArtiPoisonBagGiver::Use (bool pickup)
|
||||
{
|
||||
const PClass *MissileType = PClass::FindClass((ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None));
|
||||
if (MissileType != NULL)
|
||||
PClassActor *missiletype = PClass::FindActor(this->GetClass()->MissileName);
|
||||
if (missiletype != NULL)
|
||||
{
|
||||
AActor *mo = Spawn (MissileType, Owner->Pos(), ALLOW_REPLACE);
|
||||
AActor *mo = Spawn (missiletype, Owner->Pos(), ALLOW_REPLACE);
|
||||
if (mo != NULL)
|
||||
{
|
||||
if (mo->IsKindOf(RUNTIME_CLASS(AInventory)))
|
||||
|
@ -186,10 +177,10 @@ IMPLEMENT_CLASS (AArtiPoisonBagShooter)
|
|||
|
||||
bool AArtiPoisonBagShooter::Use (bool pickup)
|
||||
{
|
||||
const PClass *MissileType = PClass::FindClass((ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None));
|
||||
if (MissileType != NULL)
|
||||
PClassActor *missiletype = PClass::FindActor(this->GetClass()->MissileName);
|
||||
if (missiletype != NULL)
|
||||
{
|
||||
AActor *mo = P_SpawnPlayerMissile(Owner, MissileType);
|
||||
AActor *mo = P_SpawnPlayerMissile(Owner, missiletype);
|
||||
if (mo != NULL)
|
||||
{
|
||||
// automatic handling of seeker missiles
|
||||
|
@ -209,9 +200,9 @@ bool AArtiPoisonBagShooter::Use (bool pickup)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
const PClass *GetFlechetteType(AActor *other)
|
||||
PClassActor *GetFlechetteType(AActor *other)
|
||||
{
|
||||
const PClass *spawntype = NULL;
|
||||
PClassActor *spawntype = NULL;
|
||||
if (other->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
spawntype = static_cast<APlayerPawn*>(other)->FlechetteType;
|
||||
|
@ -273,8 +264,7 @@ AInventory *AArtiPoisonBag::CreateCopy (AActor *other)
|
|||
}
|
||||
|
||||
AInventory *copy;
|
||||
|
||||
const PClass *spawntype = GetFlechetteType(other);
|
||||
PClassActor *spawntype = GetFlechetteType(other);
|
||||
copy = static_cast<AInventory *>(Spawn (spawntype, 0, 0, 0, NO_REPLACE));
|
||||
copy->Amount = Amount;
|
||||
copy->MaxAmount = MaxAmount;
|
||||
|
@ -353,7 +343,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
|
|||
damage = FixedMul(damage, victim->DamageFactor);
|
||||
if (damage > 0)
|
||||
{
|
||||
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->ActorInfo->DamageFactors);
|
||||
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->DamageFactors);
|
||||
}
|
||||
if (damage > 0)
|
||||
{
|
||||
|
@ -382,6 +372,8 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn<APoisonCloud> (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE);
|
||||
|
@ -389,6 +381,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
|
|||
{
|
||||
mo->target = self->target;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -399,14 +392,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (--self->special1 <= 0)
|
||||
{
|
||||
self->SetState (self->FindState ("Death"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -417,12 +413,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagCheck)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int bobIndex;
|
||||
|
||||
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE);
|
||||
bobIndex = self->special2;
|
||||
self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1);
|
||||
self->special2 = (bobIndex + 1) & 63;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -433,10 +432,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (--self->health <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -447,6 +449,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// [RH] Check using actual velocity, although the velz < 2 check still stands
|
||||
//if (abs(self->velx) < FRACUNIT*3/2 && abs(self->vely) < FRACUNIT*3/2
|
||||
// && self->velz < 2*FRACUNIT)
|
||||
|
@ -461,4 +465,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
|
|||
self->flags &= ~MF_MISSILE;
|
||||
}
|
||||
CALL_ACTION(A_CheckThrowBomb, self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlySearch)
|
|||
// So search the sectors instead. We can't potentially find something all
|
||||
// the way on the other side of the map and we can't find invisible corpses,
|
||||
// but at least we aren't crippled on maps with lots of stuff going on.
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
validcount++;
|
||||
AActor *other = FindCorpse(self, self->Sector, 5);
|
||||
if (other != NULL)
|
||||
|
@ -67,16 +69,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlySearch)
|
|||
self->target = other;
|
||||
self->SetState(self->FindState("Buzz"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *targ = self->target;
|
||||
|
||||
if (targ == NULL || !(targ->flags & MF_CORPSE) || pr_fly() < 5)
|
||||
{
|
||||
self->SetIdle();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
angle_t ang = self->AngleTo(targ);
|
||||
|
@ -86,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
|
|||
if (!P_TryMove(self, self->X() + 6 * finecosine[ang], self->Y() + 6 * finesine[ang], true))
|
||||
{
|
||||
self->SetIdle(true);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->args[0] & 2)
|
||||
{
|
||||
|
@ -103,4 +108,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
|
|||
{
|
||||
S_Sound(self, CHAN_VOICE, self->ActiveSound, 0.5f, ATTN_STATIC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ static FRandom pr_fogspawn ("FogSpawn");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
static const char *fogs[3] =
|
||||
{
|
||||
"FogPatchSmall",
|
||||
|
@ -34,11 +36,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
|
|||
"FogPatchLarge"
|
||||
};
|
||||
|
||||
AActor *mo=NULL;
|
||||
AActor *mo = NULL;
|
||||
angle_t delta;
|
||||
|
||||
if (self->special1-- > 0) return;
|
||||
|
||||
if (self->special1-- > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
self->special1 = self->args[2]; // Reset frequency count
|
||||
|
||||
mo = Spawn (fogs[pr_fogspawn()%3], self->Pos(), ALLOW_REPLACE);
|
||||
|
@ -55,6 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
|
|||
mo->args[4] = 1; // Set to moving
|
||||
mo->special2 = pr_fogspawn()&63;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -65,16 +70,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int speed = self->args[0]<<FRACBITS;
|
||||
angle_t angle;
|
||||
int weaveindex;
|
||||
|
||||
if (!(self->args[4])) return;
|
||||
if (!self->args[4])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->args[3]-- <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death), true);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((self->args[3] % 4) == 0)
|
||||
|
@ -87,5 +97,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
|
|||
angle = self->angle>>ANGLETOFINESHIFT;
|
||||
self->velx = FixedMul(speed, finecosine[angle]);
|
||||
self->vely = FixedMul(speed, finesine[angle]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,12 @@ IMPLEMENT_CLASS (AArtiHealingRadius)
|
|||
bool AArtiHealingRadius::Use (bool pickup)
|
||||
{
|
||||
bool effective = false;
|
||||
int mode = Owner->GetClass()->Meta.GetMetaInt(APMETA_HealingRadius);
|
||||
FName mode;
|
||||
|
||||
if (Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
mode = static_cast<PClassPlayerPawn *>(Owner->GetClass())->HealingRadiusType;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
|
@ -65,8 +70,8 @@ bool AArtiHealingRadius::Use (bool pickup)
|
|||
{
|
||||
int amount = 50 + (pr_healradius() % 50);
|
||||
|
||||
if (players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana1), amount) ||
|
||||
players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana2), amount))
|
||||
if (players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana1)), amount) ||
|
||||
players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana2)), amount))
|
||||
{
|
||||
gotsome = true;
|
||||
}
|
||||
|
|
|
@ -231,6 +231,8 @@ void ASorcBall1::DoFireSpell ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
self->SpawnState += 2; // [RH] Don't spawn balls again
|
||||
|
@ -252,6 +254,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
|
|||
if (mo) mo->target = self;
|
||||
mo = Spawn("SorcBall3", pos, NO_REPLACE);
|
||||
if (mo) mo->target = self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,11 +266,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// [RH] If no parent, then die instead of crashing
|
||||
if (self->target == NULL)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Pain));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASorcBall *actor;
|
||||
|
@ -279,14 +284,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
|
||||
if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall)))
|
||||
{
|
||||
I_Error ("Corrupted sorcerer:\nTried to use a %s", RUNTIME_TYPE(self)->TypeName.GetChars());
|
||||
I_Error ("Corrupted sorcerer:\nTried to use a %s", self->GetClass()->TypeName.GetChars());
|
||||
}
|
||||
actor = static_cast<ASorcBall *> (self);
|
||||
|
||||
if (actor->target->health <= 0)
|
||||
{
|
||||
actor->SetState (actor->FindState(NAME_Pain));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
baseangle = (angle_t)parent->special1;
|
||||
|
@ -311,7 +316,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
break;
|
||||
|
||||
case SORC_STOPPING: // Balls stopping
|
||||
if ((parent->StopBall == RUNTIME_TYPE(actor)) &&
|
||||
if ((parent->StopBall == actor->GetClass()) &&
|
||||
(parent->args[1] > SORCBALL_SPEED_ROTATIONS) &&
|
||||
(absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5)))
|
||||
{
|
||||
|
@ -328,7 +333,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
break;
|
||||
|
||||
case SORC_FIRESPELL: // Casting spell
|
||||
if (parent->StopBall == RUNTIME_TYPE(actor))
|
||||
if (parent->StopBall == actor->GetClass())
|
||||
{
|
||||
// Put sorcerer into special throw spell anim
|
||||
if (parent->health > 0)
|
||||
|
@ -339,7 +344,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
break;
|
||||
|
||||
case SORC_FIRING_SPELL:
|
||||
if (parent->StopBall == RUNTIME_TYPE(actor))
|
||||
if (parent->StopBall == actor->GetClass())
|
||||
{
|
||||
if (actor->special2-- <= 0)
|
||||
{
|
||||
|
@ -377,6 +382,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
actor->SetOrigin (pos, true);
|
||||
actor->floorz = parent->floorz;
|
||||
actor->ceilingz = parent->ceilingz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -389,8 +395,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->args[3] = SORC_ACCELERATE; // speed mode
|
||||
self->args[2] = SORCBALL_TERMINAL_SPEED; // target speed
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -566,7 +575,7 @@ void ASorcBall3::CastSorcererSpell ()
|
|||
|
||||
ang1 = angle - ANGLE_45;
|
||||
ang2 = angle + ANGLE_45;
|
||||
const PClass *cls = PClass::FindClass("SorcFX3");
|
||||
PClassActor *cls = PClass::FindActor("SorcFX3");
|
||||
if (health < (SpawnHealth()/3))
|
||||
{ // Spawn 2 at a time
|
||||
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT);
|
||||
|
@ -615,7 +624,7 @@ void ASorcBall1::CastSorcererSpell ()
|
|||
|
||||
ang1 = angle + ANGLE_1*70;
|
||||
ang2 = angle - ANGLE_1*70;
|
||||
const PClass *cls = PClass::FindClass("SorcFX1");
|
||||
PClassActor *cls = PClass::FindActor("SorcFX1");
|
||||
mo = P_SpawnMissileAngle (parent, cls, ang1, 0);
|
||||
if (mo)
|
||||
{
|
||||
|
@ -662,7 +671,7 @@ void A_SorcOffense2(AActor *actor)
|
|||
delta = (finesine[index])*SORCFX4_SPREAD_ANGLE;
|
||||
delta = (delta>>FRACBITS)*ANGLE_1;
|
||||
ang1 = actor->angle + delta;
|
||||
mo = P_SpawnMissileAngle(parent, PClass::FindClass("SorcFX4"), ang1, 0);
|
||||
mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0);
|
||||
if (mo)
|
||||
{
|
||||
mo->special2 = 35*5/2; // 5 seconds
|
||||
|
@ -682,8 +691,11 @@ void A_SorcOffense2(AActor *actor)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->args[3] = SORC_ACCELERATE;
|
||||
self->args[2] = SORCBALL_INITIAL_SPEED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -696,6 +708,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
fixed_t dist = 5*FRACUNIT;
|
||||
fixed_t speed = self->Speed;
|
||||
angle_t rangle;
|
||||
|
@ -714,6 +727,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
|
|||
mo->velz = FRACUNIT*2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -727,8 +741,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_DoBounceCheck (self, "SorcererHeadScream");
|
||||
P_SeekerMissile (self,ANGLE_1*2,ANGLE_1*6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -750,6 +767,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
|
|||
// Split ball in two
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE);
|
||||
|
@ -769,6 +788,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
|
|||
mo->SetState (mo->FindState("Orbit"));
|
||||
}
|
||||
self->Destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -781,6 +801,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
fixedvec3 pos;
|
||||
AActor *parent = self->target;
|
||||
|
@ -789,7 +811,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
|
|||
if (parent == NULL)
|
||||
{
|
||||
self->Destroy();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fixed_t dist = parent->radius;
|
||||
|
@ -839,6 +861,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
|
|||
self->SetOrigin (pos, true);
|
||||
self->floorz = parent->floorz;
|
||||
self->ceilingz = parent->ceilingz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -851,6 +874,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
mo = Spawn("Bishop", self->Pos(), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
|
@ -867,6 +892,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
|
|||
}
|
||||
}
|
||||
self->Destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -877,8 +903,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcererBishopEntry)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
Spawn("SorcFX3Explosion", self->Pos(), ALLOW_REPLACE);
|
||||
S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -891,10 +920,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererBishopEntry)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX4Check)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->special2-- <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -907,6 +939,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX4Check)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE);
|
||||
self->flags &= ~MF_NOGRAVITY;
|
||||
self->gravity = FRACUNIT/8;
|
||||
|
@ -916,6 +950,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
|
|||
self->special2 = 4*FRACUNIT; // Initial bounce factor
|
||||
self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit
|
||||
self->args[3] = 5; // Bounce time in seconds
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -948,5 +983,8 @@ void A_DoBounceCheck (AActor *self, const char *sound)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BounceCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
A_DoBounceCheck (self, "SorcererBigBallExplode");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,4 +29,13 @@ class AMageWeapon : public AWeapon
|
|||
public:
|
||||
};
|
||||
|
||||
class AArtiPoisonBag : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AArtiPoisonBag, AInventory)
|
||||
public:
|
||||
bool HandlePickup (AInventory *item);
|
||||
AInventory *CreateCopy (AActor *other);
|
||||
void BeginPlay ();
|
||||
};
|
||||
|
||||
#endif //__A_HEXENGLOBAL_H__
|
||||
|
|
|
@ -55,6 +55,8 @@ void APottery1::HitFloor ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo = NULL;
|
||||
int i;
|
||||
|
||||
|
@ -71,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
|
|||
}
|
||||
S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM);
|
||||
// Spawn an item?
|
||||
const PClass *type = P_GetSpawnableType(self->args[0]);
|
||||
PClassActor *type = P_GetSpawnableType(self->args[0]);
|
||||
if (type != NULL)
|
||||
{
|
||||
if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS))
|
||||
|
@ -80,6 +82,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
|
|||
Spawn (type, self->Pos(), ALLOW_REPLACE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -90,8 +93,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PotteryChooseBit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->SetState (self->FindState(NAME_Death) + 1 + 2*(pr_bit()%5));
|
||||
self->tics = 256+(pr_bit()<<1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -102,6 +108,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryChooseBit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -112,10 +120,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
|
|||
if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self) - pmo->angle) <= ANGLE_45))
|
||||
{ // Previous state (pottery bit waiting state)
|
||||
self->SetState (self->state - 1);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lynched corpse (no heart) ------------------------------------------------
|
||||
|
@ -143,10 +152,13 @@ void AZCorpseLynchedNoHeart::PostBeginPlay ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (pr_drip() <= 128)
|
||||
{
|
||||
Spawn ("CorpseBloodDrip", self->PosPlusZ(self->height/2), ALLOW_REPLACE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -157,6 +169,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int i;
|
||||
|
||||
|
@ -182,6 +196,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
|
|||
}
|
||||
S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE);
|
||||
self->Destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -192,6 +207,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int i;
|
||||
|
||||
|
@ -200,7 +217,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
|
|||
fixed_t xo = (pr_leaf.Random2() << 14);
|
||||
fixed_t yo = (pr_leaf.Random2() << 14);
|
||||
fixed_t zo = (pr_leaf() << 14);
|
||||
mo = Spawn (pr_leaf()&1 ? PClass::FindClass ("Leaf1") : PClass::FindClass ("Leaf2"),
|
||||
mo = Spawn (pr_leaf()&1 ? PClass::FindActor ("Leaf1") : PClass::FindActor ("Leaf2"),
|
||||
self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
||||
|
||||
if (mo)
|
||||
|
@ -210,6 +227,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
|
|||
mo->special1 = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -220,10 +238,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (pr_leafthrust() <= 96)
|
||||
{
|
||||
self->velz += (pr_leafthrust()<<9)+FRACUNIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -234,11 +255,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->special1++;
|
||||
if (self->special1 >= 20)
|
||||
{
|
||||
self->SetState (NULL);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle_t ang = self->target ? self->target->angle : self->angle;
|
||||
if (pr_leafcheck() > 64)
|
||||
|
@ -247,12 +270,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
|
|||
{
|
||||
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT);
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
self->SetState (self->SpawnState + 7);
|
||||
self->velz = (pr_leafcheck()<<9)+FRACUNIT;
|
||||
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT);
|
||||
self->flags |= MF_MISSILE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -263,7 +287,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->tics = 128+(pr_shroom()<<1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -274,6 +301,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int i;
|
||||
|
||||
|
@ -292,7 +321,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
|
|||
}
|
||||
}
|
||||
// Spawn an item?
|
||||
const PClass *type = P_GetSpawnableType(self->args[0]);
|
||||
PClassActor *type = P_GetSpawnableType(self->args[0]);
|
||||
if (type != NULL)
|
||||
{
|
||||
if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS))
|
||||
|
@ -303,6 +332,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
|
|||
}
|
||||
S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_NORM);
|
||||
self->Destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Bell ---------------------------------------------------------------------
|
||||
|
@ -332,6 +362,8 @@ void AZBell::Activate (AActor *activator)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->flags |= MF_NOGRAVITY;
|
||||
self->height <<= 2;
|
||||
if (self->special)
|
||||
|
@ -340,6 +372,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
|
|||
self->args[1], self->args[2], self->args[3], self->args[4]);
|
||||
self->special = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -350,9 +383,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BellReset2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->flags |= MF_SHOOTABLE;
|
||||
self->flags &= ~MF_CORPSE;
|
||||
self->flags6 &= ~MF6_KILLED;
|
||||
self->health = 5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ static const char *WispTypes[2] =
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
fixed_t dist;
|
||||
fixed_t an;
|
||||
|
||||
|
@ -40,6 +42,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
|
|||
FixedMul(dist, finesine[an]),
|
||||
60 * FRACUNIT), ALLOW_REPLACE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -50,11 +53,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
fixed_t dist;
|
||||
fixed_t an;
|
||||
AActor *mo;
|
||||
|
||||
A_Chase (self);
|
||||
A_Chase (stack, self);
|
||||
if (pr_iceguychase() < 128)
|
||||
{
|
||||
dist = ((pr_iceguychase()-128)*self->radius)>>7;
|
||||
|
@ -72,6 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
|
|||
mo->target = self;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -82,13 +88,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if(!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle+ANG90, 40*FRACUNIT), self, self->target, PClass::FindClass ("IceGuyFX"));
|
||||
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle-ANG90, 40*FRACUNIT), self, self->target, PClass::FindClass ("IceGuyFX"));
|
||||
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX"));
|
||||
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX"));
|
||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -99,11 +108,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->velx = 0;
|
||||
self->vely = 0;
|
||||
self->velz = 0;
|
||||
self->height = self->GetDefault()->height;
|
||||
CALL_ACTION(A_FreezeDeathChunks, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -114,17 +126,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mo = P_SpawnMissileAngleZ (self, self->Z()+3*FRACUNIT,
|
||||
PClass::FindClass("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT));
|
||||
PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT));
|
||||
if (mo)
|
||||
{
|
||||
mo->target = self->target;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,10 +74,10 @@ void A_KSpiritRoam (AActor *);
|
|||
void A_KBolt (AActor *);
|
||||
void A_KBoltRaise (AActor *);
|
||||
|
||||
void KoraxFire (AActor *actor, const PClass *type, int arm);
|
||||
void KoraxFire (AActor *actor, PClassActor *type, int arm);
|
||||
void KSpiritInit (AActor *spirit, AActor *korax);
|
||||
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z,
|
||||
AActor *source, AActor *dest, const PClass *type);
|
||||
AActor *source, AActor *dest, PClassActor *type);
|
||||
|
||||
extern void SpawnSpiritTail (AActor *spirit);
|
||||
|
||||
|
@ -89,6 +89,8 @@ extern void SpawnSpiritTail (AActor *spirit);
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *spot;
|
||||
|
||||
if ((!self->special2) && (self->health <= (self->SpawnHealth()/2)))
|
||||
|
@ -103,10 +105,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
|
|||
P_StartScript (self, NULL, 249, NULL, NULL, 0, 0);
|
||||
self->special2 = 1; // Don't run again
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!self->target) return;
|
||||
if (self->target == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (pr_koraxchase()<30)
|
||||
{
|
||||
self->SetState (self->MissileState);
|
||||
|
@ -140,6 +145,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -150,17 +156,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int i;
|
||||
|
||||
// Spawn 6 spirits equalangularly
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
mo = P_SpawnMissileAngle (self, PClass::FindClass("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT);
|
||||
if (mo) KSpiritInit (mo, self);
|
||||
mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT);
|
||||
if (mo)
|
||||
{
|
||||
KSpiritInit (mo, self);
|
||||
}
|
||||
}
|
||||
|
||||
P_StartScript (self, NULL, 255, NULL, NULL, 0, 0); // Death script
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -190,6 +202,8 @@ void KSpiritInit (AActor *spirit, AActor *korax)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (pr_koraxdecide()<220)
|
||||
{
|
||||
self->SetState (self->FindState("Attack"));
|
||||
|
@ -198,6 +212,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
|
|||
{
|
||||
self->SetState (self->FindState("Command"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -208,6 +223,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
static const struct { const char *type, *sound; } choices[6] =
|
||||
{
|
||||
{ "WraithFX1", "WraithMissileFire" },
|
||||
|
@ -220,11 +237,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
|
|||
|
||||
int type = pr_koraxmissile()%6;
|
||||
int i;
|
||||
const PClass *info;
|
||||
PClassActor *info;
|
||||
|
||||
S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM);
|
||||
|
||||
info = PClass::FindClass (choices[type].type);
|
||||
info = PClass::FindActor(choices[type].type);
|
||||
if (info == NULL)
|
||||
{
|
||||
I_Error ("Unknown Korax missile: %s\n", choices[type].type);
|
||||
|
@ -236,6 +253,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
|
|||
{
|
||||
KoraxFire (self, info, i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -248,6 +266,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
angle_t ang;
|
||||
int numcommands;
|
||||
|
||||
|
@ -271,6 +290,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
|
|||
}
|
||||
|
||||
P_StartScript (self, NULL, 250+(pr_koraxcommand()%numcommands), NULL, NULL, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -288,7 +308,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void KoraxFire (AActor *actor, const PClass *type, int arm)
|
||||
void KoraxFire (AActor *actor, PClassActor *type, int arm)
|
||||
{
|
||||
static const int extension[6] =
|
||||
{
|
||||
|
@ -405,6 +425,8 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->health-- <= 0)
|
||||
{
|
||||
S_Sound (self, CHAN_VOICE, "SpiritDie", 1, ATTN_NORM);
|
||||
|
@ -423,6 +445,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam)
|
|||
S_Sound (self, CHAN_VOICE, "SpiritActive", 1, ATTN_NONE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -433,11 +456,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KBolt)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
// Countdown lifetime
|
||||
if (self->special1-- <= 0)
|
||||
{
|
||||
self->Destroy ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -448,6 +474,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBolt)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
fixed_t z;
|
||||
|
||||
|
@ -466,6 +494,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
|
|||
{
|
||||
// Maybe cap it off here
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -475,7 +504,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
|
|||
//============================================================================
|
||||
|
||||
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z,
|
||||
AActor *source, AActor *dest, const PClass *type)
|
||||
AActor *source, AActor *dest, PClassActor *type)
|
||||
{
|
||||
AActor *th;
|
||||
angle_t an;
|
||||
|
|
|
@ -51,6 +51,8 @@ int AFrostMissile::DoSpecialDamage (AActor *victim, int damage, FName damagetype
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
@ -62,14 +64,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
S_Sound (self, CHAN_WEAPON, "MageShardsFire", 1, ATTN_NORM);
|
||||
|
||||
|
@ -99,6 +101,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
|||
mo->args[0] = 3; // Mark Initial shard as super damage
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -109,11 +112,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int spawndir = self->special1;
|
||||
int spermcount = self->special2;
|
||||
|
||||
if (spermcount <= 0) return; // No sperm left
|
||||
if (spermcount <= 0)
|
||||
{
|
||||
return 0; // No sperm left
|
||||
}
|
||||
self->special2 = 0;
|
||||
spermcount--;
|
||||
|
||||
|
@ -173,4 +181,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
|
|||
mo->args[0] = (spermcount==3)?2:0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -126,11 +126,14 @@ int ALightningZap::SpecialMissileHit (AActor *thing)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningReady)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
DoReadyWeapon(self);
|
||||
if (pr_lightningready() < 160)
|
||||
{
|
||||
S_Sound (self, CHAN_WEAPON, "MageLightningReady", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -141,6 +144,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningReady)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *cMo;
|
||||
AActor *target = NULL;
|
||||
int zigZag;
|
||||
|
@ -149,7 +154,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
|
|||
{
|
||||
if (self->lastenemy == NULL)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
self->SetZ(self->floorz);
|
||||
target = self->lastenemy->tracer;
|
||||
|
@ -196,6 +201,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
|
|||
P_ThrustMobj (self, self->angle, self->Speed>>1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,18 +213,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap));
|
||||
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
|
||||
AActor *mo;
|
||||
fixed_t deltaZ;
|
||||
|
||||
if (lightning == NULL)
|
||||
{
|
||||
lightning = PClass::FindActor(NAME_LightningZap);
|
||||
}
|
||||
|
||||
CALL_ACTION(A_LightningClip, self);
|
||||
|
||||
self->health -= 8;
|
||||
if (self->health <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->flags3 & MF3_FLOORHUGGER)
|
||||
{
|
||||
|
@ -251,6 +263,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
|
|||
{
|
||||
S_Sound (self, CHAN_BODY, self->ActiveSound, 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -261,9 +274,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
|
||||
{
|
||||
ACTION_PARAM_START(2);
|
||||
ACTION_PARAM_CLASS(floor, 0);
|
||||
ACTION_PARAM_CLASS(ceiling, 1);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS_OPT(floor, AActor) { floor = PClass::FindActor("LightningFloor"); }
|
||||
PARAM_CLASS_OPT(ceiling, AActor) { ceiling = PClass::FindActor("LightningCeiling"); }
|
||||
|
||||
AActor *fmo, *cmo;
|
||||
|
||||
|
@ -291,6 +304,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
|
|||
weapon->DepleteAmmo (weapon->bAltFire);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -301,6 +315,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = self->lastenemy;
|
||||
|
@ -316,6 +332,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
|
|||
self->vely = mo->vely;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -326,17 +343,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
|
||||
{
|
||||
const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap));
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if (lightning == NULL)
|
||||
{
|
||||
lightning = PClass::FindActor(NAME_LightningZap);
|
||||
}
|
||||
mo = Spawn(lightning, self->Pos(), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
mo->SetState (mo->FindState (NAME_Death));
|
||||
mo->velz = 40*FRACUNIT;
|
||||
mo->Damage = 0;
|
||||
mo->Damage = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -347,6 +370,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningRemove)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = self->lastenemy;
|
||||
|
@ -355,4 +380,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningRemove)
|
|||
mo->lastenemy = NULL;
|
||||
P_ExplodeMissile (mo, NULL, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -119,20 +119,22 @@ void MStaffSpawn (AActor *pmo, angle_t angle)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
player_t *player;
|
||||
AActor *linetarget;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon);
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
angle = self->angle;
|
||||
|
||||
|
@ -151,6 +153,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
|
|||
MStaffSpawn (self, angle+ANGLE_1*5);
|
||||
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
|
||||
weapon->MStaffCount = 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -161,6 +164,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL)
|
||||
{
|
||||
AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon);
|
||||
|
@ -169,6 +174,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
|
|||
weapon->MStaffCount--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -179,11 +185,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if ((self->tracer == 0) && (pr_mstafftrack()<50))
|
||||
{
|
||||
self->tracer = P_RoughMonsterSearch (self, 10, true);
|
||||
}
|
||||
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -239,13 +248,17 @@ void MStaffSpawn2 (AActor *actor, angle_t angle)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MageAttack)
|
||||
{
|
||||
if (!self->target) return;
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->target == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
angle_t angle;
|
||||
angle = self->angle;
|
||||
MStaffSpawn2 (self, angle);
|
||||
MStaffSpawn2 (self, angle-ANGLE_1*5);
|
||||
MStaffSpawn2 (self, angle+ANGLE_1*5);
|
||||
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ void APigPlayer::MorphPlayerThink ()
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
angle_t angle;
|
||||
int damage;
|
||||
int slope;
|
||||
|
@ -69,7 +71,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
|||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
damage = 3+(pr_snoutattack()&3);
|
||||
|
@ -85,6 +87,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
|||
S_Sound(player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -95,9 +98,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_PigPain)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
CALL_ACTION(A_Pain, self);
|
||||
if (self->Z() <= self->floorz)
|
||||
{
|
||||
self->velz = FRACUNIT*7/2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,11 @@ static FRandom pr_delaygib ("DelayGib");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->renderflags &= ~RF_INVISIBLE;
|
||||
self->floorclip = 24*FRACUNIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -37,8 +40,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->renderflags |= RF_INVISIBLE;
|
||||
self->floorclip = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -50,7 +56,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->floorclip -= 4*FRACUNIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -61,7 +70,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->floorclip += 4*FRACUNIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -74,21 +86,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->MissileState != NULL)
|
||||
{
|
||||
if (pr_serpenthump() > 30)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
else if (pr_serpenthump() < 40)
|
||||
{ // Missile attack
|
||||
self->SetState (self->MeleeState);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (pr_serpenthump() > 3)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!self->CheckMeleeRange ())
|
||||
{ // The hump shouldn't occur when within melee range
|
||||
|
@ -102,6 +116,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide)
|
|||
S_Sound (self, CHAN_BODY, "SerpentActive", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -112,16 +127,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->MissileState != NULL)
|
||||
{
|
||||
if (!self->CheckMeleeRange ())
|
||||
{
|
||||
self->SetState (self->FindState ("Attack"));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (P_CheckMeleeRange2 (self))
|
||||
|
@ -139,6 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
|
|||
self->SetState (self->FindState ("Attack"));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -149,14 +167,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentChooseAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target || self->CheckMeleeRange())
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->MissileState != NULL)
|
||||
{
|
||||
self->SetState (self->MissileState);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -167,9 +188,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentChooseAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (self->CheckMeleeRange ())
|
||||
{
|
||||
|
@ -182,6 +205,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
|
|||
{
|
||||
CALL_ACTION(A_SerpentCheckForAttack, self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -192,6 +216,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
static const char *GibTypes[] =
|
||||
{
|
||||
|
@ -215,6 +241,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
|
|||
mo->floorclip = 6*FRACUNIT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -225,7 +252,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FloatGib)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->floorclip -= FRACUNIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -236,7 +266,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatGib)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SinkGib)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->floorclip += FRACUNIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -247,7 +280,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SinkGib)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DelayGib)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->tics -= pr_delaygib()>>2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -258,6 +294,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DelayGib)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->Z() <= self->floorz)
|
||||
{
|
||||
if (Terrains[P_GetThingFloorType(self)].IsLiquid)
|
||||
|
@ -270,5 +308,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck)
|
|||
self->SetState (self->FindState(NAME_Death));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,16 +78,21 @@ void AThrustFloor::Deactivate (AActor *activator)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->special2 = 5; // Raise speed
|
||||
self->args[0] = 1; // Mark as up
|
||||
self->floorclip = 0;
|
||||
self->flags = MF_SOLID;
|
||||
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
|
||||
self->special1 = 0L;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->special2 = 5; // Raise speed
|
||||
self->args[0] = 0; // Mark as down
|
||||
self->floorclip = self->GetDefault()->height;
|
||||
|
@ -96,11 +101,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
|
|||
self->renderflags = RF_INVISIBLE;
|
||||
static_cast<AThrustFloor *>(self)->DirtClump =
|
||||
Spawn("DirtClump", self->Pos(), ALLOW_REPLACE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AThrustFloor *actor = static_cast<AThrustFloor *>(self);
|
||||
|
||||
if (A_RaiseMobj (actor, self->special2*FRACUNIT))
|
||||
|
@ -123,10 +131,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
|
|||
if (pr_thrustraise()<40)
|
||||
P_SpawnDirt (actor, actor->radius);
|
||||
actor->special2++; // Increase raise speed
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (A_SinkMobj (self, 6*FRACUNIT))
|
||||
{
|
||||
self->args[0] = 0;
|
||||
|
@ -135,10 +146,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
|
|||
else
|
||||
self->SetState (self->FindState ("ThrustInit1"), true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *thing;
|
||||
FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), self->radius));
|
||||
while ((thing = it.Next()))
|
||||
|
@ -158,5 +172,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
|
|||
P_TraceBleed (newdam > 0 ? newdam : 10001, thing);
|
||||
self->args[1] = 1; // Mark thrust thing as bloody
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ IMPLEMENT_CLASS (AArtiDarkServant)
|
|||
|
||||
bool AArtiDarkServant::Use (bool pickup)
|
||||
{
|
||||
AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindClass ("SummoningDoll"));
|
||||
AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindActor("SummoningDoll"));
|
||||
if (mo)
|
||||
{
|
||||
mo->target = Owner;
|
||||
|
@ -49,6 +49,8 @@ bool AArtiDarkServant::Use (bool pickup)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Summon)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AMinotaurFriend *mo;
|
||||
|
||||
mo = Spawn<AMinotaurFriend> (self->Pos(), ALLOW_REPLACE);
|
||||
|
@ -59,7 +61,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
|
|||
mo->Destroy ();
|
||||
AActor *arti = Spawn<AArtiDarkServant> (self->Pos(), ALLOW_REPLACE);
|
||||
if (arti) arti->flags |= MF_DROPPED;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mo->StartTime = level.maptime;
|
||||
|
@ -79,4 +81,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
|
|||
Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE);
|
||||
S_Sound (self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -65,30 +65,41 @@ static void TeloSpawn (AActor *source, const char *type)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnA)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
TeloSpawn (self, "TelOtherFX2");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnB)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
TeloSpawn (self, "TelOtherFX3");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnC)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
TeloSpawn (self, "TelOtherFX4");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnD)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
TeloSpawn (self, "TelOtherFX5");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_CheckTeleRing)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->special1-- <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -29,6 +29,8 @@ static FRandom pr_wraithfx4 ("WraithFX4");
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->AddZ(48<<FRACBITS);
|
||||
|
||||
// [RH] Make sure the wraith didn't go into the ceiling
|
||||
|
@ -38,6 +40,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
|
|||
}
|
||||
|
||||
self->special1 = 0; // index into floatbob
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -48,11 +51,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
self->renderflags &= ~RF_INVISIBLE;
|
||||
self->flags2 &= ~MF2_NONSHOOTABLE;
|
||||
self->flags3 &= ~MF3_DONTBLAST;
|
||||
self->flags |= MF_SHOOTABLE|MF_SOLID;
|
||||
self->floorclip = self->height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -63,6 +69,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (A_RaiseMobj (self, 2*FRACUNIT))
|
||||
{
|
||||
// Reached it's target height
|
||||
|
@ -75,6 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
|
|||
}
|
||||
|
||||
P_SpawnDirt (self, self->radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -85,6 +94,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int amount;
|
||||
|
||||
// Steal health from target and give to self
|
||||
|
@ -94,6 +105,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee)
|
|||
P_DamageMobj (self->target, self, self, amount, NAME_Melee);
|
||||
self->health += amount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -104,6 +116,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
angle_t angle;
|
||||
int i;
|
||||
|
@ -130,6 +144,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
|
|||
mo->floorclip = 10*FRACUNIT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -142,6 +157,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
AActor *mo;
|
||||
int numdropped = pr_wraithfx3()%15;
|
||||
|
||||
|
@ -159,6 +176,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
|
|||
mo->target = self;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -234,6 +252,8 @@ void A_WraithFX4 (AActor *self)
|
|||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
int weaveindex = self->special1;
|
||||
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8);
|
||||
self->special1 = (weaveindex + 2) & 63;
|
||||
|
@ -242,6 +262,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
|
|||
// P_SetMobjState(self, S_WRAITH_RAISE2);
|
||||
// return;
|
||||
// }
|
||||
A_Chase (self);
|
||||
A_Chase (stack, self);
|
||||
A_WraithFX4 (self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -45,9 +45,7 @@ struct cluster_info_t;
|
|||
class FScanner;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma data_seg(".yreg$u")
|
||||
#pragma data_seg()
|
||||
|
||||
#pragma section(".yreg$u",read)
|
||||
#define MSVC_YSEG __declspec(allocate(".yreg$u"))
|
||||
#define GCC_YSEG
|
||||
#else
|
||||
|
|
|
@ -371,12 +371,12 @@ level_info_t *level_info_t::CheckLevelRedirect ()
|
|||
{
|
||||
if (RedirectType != NAME_None)
|
||||
{
|
||||
const PClass *type = PClass::FindClass(RedirectType);
|
||||
PClassActor *type = PClass::FindActor(RedirectType);
|
||||
if (type != NULL)
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i] && players[i].mo->FindInventory (type))
|
||||
if (playeringame[i] && players[i].mo->FindInventory(type))
|
||||
{
|
||||
// check for actual presence of the map.
|
||||
if (P_CheckMapData(RedirectMapName))
|
||||
|
|
|
@ -68,7 +68,7 @@ bool AArtiTeleport::Use (bool pickup)
|
|||
|
||||
bool P_AutoUseChaosDevice (player_t *player)
|
||||
{
|
||||
AInventory *arti = player->mo->FindInventory(PClass::FindClass("ArtiTeleport"));
|
||||
AInventory *arti = player->mo->FindInventory(PClass::FindActor("ArtiTeleport"));
|
||||
|
||||
if (arti != NULL)
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue