# 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:
Christoph Oelckers 2016-02-05 12:31:41 +01:00
commit dda73b531c
260 changed files with 25409 additions and 9004 deletions

3
.gitignore vendored
View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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)

View file

@ -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());
}

View file

@ -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)
{

View file

@ -50,7 +50,7 @@ public:
void DoPickupSpecial (AActor *toucher);
void Serialize(FArchive &arc);
private:
const PClass *DetermineType ();
PClassActor *DetermineType ();
AInventory *RealPickup;
public:
bool droppedbymonster;

View file

@ -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);

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -43,7 +43,7 @@
class FScanner;
class FDecalTemplate;
struct FDecalAnimator;
struct PClass;
class PClass;
class DBaseDecal;
struct side_t;

View file

@ -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)

View file

@ -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__

View file

@ -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.
//
//==========================================================================

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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.

View file

@ -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;
}

View file

@ -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)

View file

@ -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));

View file

@ -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)

View file

@ -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

View file

@ -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.
{

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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 ? &param[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 ? &param[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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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",

View file

@ -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:

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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__

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
//===========================================================================

View file

@ -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;
}

View file

@ -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

View file

@ -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))

View file

@ -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