Merge branch 'scripting'

Conflicts:
	src/actor.h
	src/g_doom/a_doomweaps.cpp
	src/g_hexen/a_blastradius.cpp
	src/p_enemy.cpp
	src/p_enemy.h
	src/thingdef/thingdef.h
	src/thingdef/thingdef_codeptr.cpp
	wadsrc/static/actors/constants.txt
This commit is contained in:
Randy Heit 2016-02-04 15:15:29 -06:00
commit b3b0886b64
230 changed files with 24074 additions and 8654 deletions

3
.gitignore vendored
View file

@ -21,6 +21,9 @@
/src/xlat/xlat_parser.c /src/xlat/xlat_parser.c
/src/xlat/xlat_parser.h /src/xlat/xlat_parser.h
/src/xlat/xlat_parser.out /src/xlat/xlat_parser.out
/src/zscript/zcc-parse.c
/src/zscript/zcc-parse.h
/src/zscript/zcc-parse.out
/tools/*/debug /tools/*/debug
/tools/*/release /tools/*/release
/tools/*/*.exe /tools/*/*.exe

View file

@ -685,6 +685,12 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CUR
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y ) DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h
COMMAND ${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 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 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 ) DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re )
@ -751,6 +757,7 @@ file( GLOB HEADER_FILES
textures/*.h textures/*.h
thingdef/*.h thingdef/*.h
xlat/*.h xlat/*.h
zscript/*.h
*.h *.h
) )
@ -837,6 +844,9 @@ set( NOT_COMPILED_SOURCE_FILES
xlat/xlat_parser.y xlat/xlat_parser.y
xlat_parser.c xlat_parser.c
xlat_parser.h 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 # We could have the ASM macro add these files, but it wouldn't add all
# platforms. # platforms.
@ -1136,7 +1146,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
thingdef/thingdef_data.cpp thingdef/thingdef_data.cpp
thingdef/thingdef_exp.cpp thingdef/thingdef_exp.cpp
thingdef/thingdef_expression.cpp thingdef/thingdef_expression.cpp
thingdef/thingdef_function.cpp
thingdef/thingdef_parse.cpp thingdef/thingdef_parse.cpp
thingdef/thingdef_properties.cpp thingdef/thingdef_properties.cpp
thingdef/thingdef_states.cpp thingdef/thingdef_states.cpp
@ -1171,6 +1180,14 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
r_data/renderstyle.cpp r_data/renderstyle.cpp
r_data/r_interpolate.cpp r_data/r_interpolate.cpp
r_data/r_translate.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 zzautozend.cpp
) )
@ -1197,6 +1214,7 @@ include_directories( .
thingdef thingdef
timidity timidity
xlat xlat
zscript
../gdtoa ../gdtoa
../dumb/include ../dumb/include
${CMAKE_BINARY_DIR}/gdtoa ${CMAKE_BINARY_DIR}/gdtoa
@ -1318,4 +1336,5 @@ source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_sh
source_group("Versioning" FILES version.h win32/zdoom.rc) source_group("Versioning" FILES version.h win32/zdoom.rc)
source_group("Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+") 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("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) 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) #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") #pragma comment(linker, "/merge:.areg=.rdata /merge:.creg=.rdata /merge:.greg=.rdata")
void *ARegHead = 0; #pragma comment(linker, "/merge:.yreg=.rdata")
#pragma data_seg(".creg$a") #pragma section(".areg$a",read)
void *CRegHead = 0; __declspec(allocate(".areg$a")) void *const ARegHead = 0;
#pragma data_seg(".greg$a") #pragma section(".creg$a",read)
void *GRegHead = 0; __declspec(allocate(".creg$a")) void *const CRegHead = 0;
#pragma data_seg(".mreg$a") #pragma section(".greg$a",read)
void *MRegHead = 0; __declspec(allocate(".greg$a")) void *const GRegHead = 0;
#pragma data_seg(".yreg$a") #pragma section(".yreg$a",read)
void *YRegHead = 0; __declspec(allocate(".yreg$a")) void *const YRegHead = 0;
#pragma data_seg()
// We want visual styles support under XP // We want visual styles support under XP
#if defined _M_IX86 #if defined _M_IX86
@ -88,11 +90,15 @@ void *YRegHead = 0;
#include "doomtype.h" #include "doomtype.h"
void *ARegHead __attribute__((section(SECTION_AREG))) = 0; // I don't know of an easy way to merge sections together with the GNU linker,
void *CRegHead __attribute__((section(SECTION_CREG))) = 0; // so GCC users will see all of these sections appear in the final executable.
void *GRegHead __attribute__((section(SECTION_GREG))) = 0; // (There are linker scripts, but that apparently involves extracting the
void *MRegHead __attribute__((section(SECTION_MREG))) = 0; // default script from ld and then modifying it.)
void *YRegHead __attribute__((section(SECTION_YREG))) = 0;
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 #else

View file

@ -42,6 +42,8 @@
#include "tflags.h" #include "tflags.h"
struct subsector_t; struct subsector_t;
class PClassAmmo;
// //
// NOTES: AActor // NOTES: AActor
// //
@ -278,7 +280,7 @@ enum ActorFlag4
enum ActorFlag5 enum ActorFlag5
{ {
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from. 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_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this 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 MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
@ -560,67 +562,54 @@ inline AActor *GetDefaultByType (const PClass *type)
template<class T> template<class T>
inline T *GetDefault () inline T *GetDefault ()
{ {
return (T *)(RUNTIME_CLASS(T)->Defaults); return (T *)(RUNTIME_CLASS_CASTLESS(T)->Defaults);
} }
struct line_t; struct line_t;
struct secplane_t; struct secplane_t;
struct FStrifeDialogueNode; 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 struct fixedvec3
{ {
fixed_t x, y, z; 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 struct fixedvec2
{ {
fixed_t x, y; fixed_t x, y;
};
struct FDropItem operator FVector2()
{
FName Name;
int probability;
int amount;
FDropItem * Next;
};
class FDropItemPtrArray : public TArray<FDropItem *>
{
public:
~FDropItemPtrArray()
{ {
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... 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 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. // Map Object definition.
class AActor : public DThinker class AActor : public DThinker
{ {
DECLARE_CLASS (AActor, DThinker) DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
AActor () throw(); AActor () throw();
@ -639,14 +628,14 @@ public:
void Serialize (FArchive &arc); 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 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 // Return true if the monster should use a missile attack, false for melee
bool SuggestMissileAttack (fixed_t dist); bool SuggestMissileAttack (fixed_t dist);
@ -727,7 +716,7 @@ public:
// Take the amount value of an item from the inventory list. // Take the amount value of an item from the inventory list.
// If nothing is left, the item may be destroyed. // If nothing is left, the item may be destroyed.
// Returns true if the initial item count is positive. // 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. // Uses an item and removes it from the inventory.
virtual bool UseInventory (AInventory *item); virtual bool UseInventory (AInventory *item);
@ -742,21 +731,21 @@ public:
bool CheckLocalView (int playernum) const; bool CheckLocalView (int playernum) const;
// Finds the first item of a particular type. // 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); AInventory *FindInventory (FName type);
template<class T> T *FindInventory () 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. // 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. // Returns the first item held with IF_INVBAR set.
AInventory *FirstInv (); AInventory *FirstInv ();
// Tries to give the actor some ammo. // 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. // Destroys all the inventory the actor is holding.
void DestroyAllInventory (); void DestroyAllInventory ();
@ -810,8 +799,9 @@ public:
void Crash(); void Crash();
// Return starting health adjusted by skill level // Return starting health adjusted by skill level
int SpawnHealth(); int SpawnHealth() const;
int GibHealth(); int GetGibHealth() const;
fixed_t GetCameraHeight() const;
inline bool isMissile(bool precise=true) inline bool isMissile(bool precise=true)
{ {
@ -826,7 +816,7 @@ public:
PalEntry GetBloodColor() const PalEntry GetBloodColor() const
{ {
return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor); return GetClass()->BloodColor;
} }
// These also set CF_INTERPVIEW for players. // These also set CF_INTERPVIEW for players.
@ -834,22 +824,25 @@ public:
void SetAngle(angle_t ang, bool interpolate); void SetAngle(angle_t ang, bool interpolate);
void SetRoll(angle_t roll, 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) if (type == 0)
{ {
bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); bloodcls = PClass::FindActor(GetClass()->BloodType);
} }
else if (type == 1) else if (type == 1)
{ {
bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter)); bloodcls = PClass::FindActor(GetClass()->BloodType2);
} }
else if (type == 2) 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) if (bloodcls != NULL)
{ {
@ -1020,7 +1013,7 @@ public:
fixed_t velx, vely, velz; // velocity fixed_t velx, vely, velz; // velocity
SDWORD tics; // state tic counter SDWORD tics; // state tic counter
FState *state; FState *state;
SDWORD Damage; // For missiles and monster railgun VMFunction *Damage; // For missiles and monster railgun
int projectileKickback; int projectileKickback;
ActorFlags flags; ActorFlags flags;
ActorFlags2 flags2; // Heretic flags ActorFlags2 flags2; // Heretic flags
@ -1144,8 +1137,8 @@ public:
FNameNoInit PainType; FNameNoInit PainType;
FNameNoInit DeathType; FNameNoInit DeathType;
const PClass *TeleFogSourceType; PClassActor *TeleFogSourceType;
const PClass *TeleFogDestType; PClassActor *TeleFogDestType;
int RipperLevel; int RipperLevel;
int RipLevelMin; int RipLevelMin;
int RipLevelMax; int RipLevelMax;
@ -1200,18 +1193,18 @@ public:
FState *FindState (FName label) const 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 FState *FindState (FName label, FName sublabel, bool exact = false) const
{ {
FName names[] = { label, sublabel }; 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 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; bool HasSpecialDeathStates () const;
@ -1356,7 +1349,7 @@ public:
do do
{ {
actor = FActorIterator::Next (); actor = FActorIterator::Next ();
} while (actor && !actor->IsKindOf (RUNTIME_CLASS(T))); } while (actor && !actor->IsKindOf (RUNTIME_TEMPLATE_CLASS(T)));
return static_cast<T *>(actor); return static_cast<T *>(actor);
} }
}; };
@ -1383,12 +1376,11 @@ public:
bool P_IsTIDUsed(int tid); bool P_IsTIDUsed(int tid);
int P_FindUniqueTID(int start_tid, int limit); 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); return AActor::StaticSpawn (type, x, y, z, allowreplacement);
} }
inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowreplacement)
inline AActor *Spawn (const PClass *type, const fixedvec3 &pos, replace_t allowreplacement)
{ {
return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement); return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement);
} }
@ -1410,7 +1402,7 @@ inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowrepl
template<class T> template<class T>
inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) 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> template<class T>

View file

@ -66,13 +66,8 @@ enum AAPTR
AActor *COPY_AAPTR(AActor *origin, int selector); 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 enum PTROP
{ {
PTROP_UNSAFETARGET = 1, PTROP_UNSAFETARGET = 1,
PTROP_UNSAFEMASTER = 2, PTROP_UNSAFEMASTER = 2,
PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER

View file

@ -36,7 +36,8 @@
#define AUTOSEGS_H #define AUTOSEGS_H
#define REGMARKER(x) (x) #define REGMARKER(x) (x)
typedef void *REGINFO; typedef void * const REGINFO;
typedef void * NCREGINFO;
// List of Action functons // List of Action functons
extern REGINFO ARegHead; extern REGINFO ARegHead;
@ -50,10 +51,6 @@ extern REGINFO CRegTail;
extern REGINFO GRegHead; extern REGINFO GRegHead;
extern REGINFO GRegTail; extern REGINFO GRegTail;
// List of variables
extern REGINFO MRegHead;
extern REGINFO MRegTail;
// List of MAPINFO map options // List of MAPINFO map options
extern REGINFO YRegHead; extern REGINFO YRegHead;
extern REGINFO YRegTail; extern REGINFO YRegTail;
@ -76,7 +73,7 @@ class FAutoSegIterator
} }
Probe = Head; Probe = Head;
} }
REGINFO operator*() const NCREGINFO operator*() const
{ {
return *Probe; return *Probe;
} }

View file

@ -270,7 +270,7 @@ void InitBotStuff()
{ {
w->MoveCombatDist = botinits[i].movecombatdist; w->MoveCombatDist = botinits[i].movecombatdist;
w->WeaponFlags |= botinits[i].weaponflags; 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 // FIXME
AWeapon *heldWeapon; AWeapon *heldWeapon;
heldWeapon = static_cast<AWeapon *> (player->mo->FindInventory (item->GetClass())); heldWeapon = dyn_cast<AWeapon>(player->mo->FindInventory(item->GetClass()));
if (heldWeapon != NULL) if (heldWeapon != NULL)
{ {
if (!weapgiveammo) if (!weapgiveammo)
@ -343,7 +343,7 @@ void DBot::WhatToGet (AActor *item)
else if (item->IsKindOf (RUNTIME_CLASS(AAmmo))) else if (item->IsKindOf (RUNTIME_CLASS(AAmmo)))
{ {
AAmmo *ammo = static_cast<AAmmo *> (item); AAmmo *ammo = static_cast<AAmmo *> (item);
const PClass *parent = ammo->GetParentAmmo (); PClassActor *parent = ammo->GetParentAmmo ();
AInventory *holdingammo = player->mo->FindInventory (parent); AInventory *holdingammo = player->mo->FindInventory (parent);
if (holdingammo != NULL && holdingammo->Amount >= holdingammo->MaxAmount) if (holdingammo != NULL && holdingammo->Amount >= holdingammo->MaxAmount)

View file

@ -30,8 +30,6 @@
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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> #include <math.h>
@ -929,8 +927,8 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha
if (FilterName != NULL) if (FilterName != NULL)
{ {
FilterClass = PClass::FindClass(FilterName); FilterClass = PClass::FindActor(FilterName);
if (FilterClass == NULL || FilterClass->ActorInfo == NULL) if (FilterClass == NULL)
{ {
Printf("%s is not an actor class.\n", FilterName); Printf("%s is not an actor class.\n", FilterName);
return; 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) // Print secret info (submitted by Karl Murks)

View file

@ -62,8 +62,6 @@
#include "decallib.h" #include "decallib.h"
#include "v_palette.h" #include "v_palette.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "thingdef/thingdef.h"
#include "thingdef/thingdef_exp.h"
#include "vectors.h" #include "vectors.h"
#include "dobject.h" #include "dobject.h"
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
@ -72,6 +70,7 @@
#include "doomerrors.h" #include "doomerrors.h"
#include "p_effect.h" #include "p_effect.h"
#include "farchive.h" #include "farchive.h"
#include "vmbuilder.h"
// [SO] Just the way Randy said to do it :) // [SO] Just the way Randy said to do it :)
// [RH] Made this CVAR_SERVERINFO // [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. // 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 // 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 // specifies that a thing should be hanging from the ceiling but doesn't specify
@ -110,7 +109,7 @@ struct StateMapper
{ {
FState *State; FState *State;
int StateSpan; int StateSpan;
const PClass *Owner; PClassActor *Owner;
bool OwnerIsPickup; bool OwnerIsPickup;
}; };
@ -121,7 +120,7 @@ static TArray<StateMapper> StateMap;
static TArray<FSoundID> SoundMap; static TArray<FSoundID> SoundMap;
// Names of different actor types, in original Doom 2 order // 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): // bit flags for PatchThing (a .bex extension):
struct BitName struct BitName
@ -142,8 +141,8 @@ struct StyleName
static TArray<StyleName> StyleNames; static TArray<StyleName> StyleNames;
static TArray<const PClass *> AmmoNames; static TArray<PClassAmmo *> AmmoNames;
static TArray<const PClass *> WeaponNames; static TArray<PClassActor *> WeaponNames;
// DeHackEd trickery to support MBF-style parameters // DeHackEd trickery to support MBF-style parameters
// List of states that are hacked to use a codepointer // 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 // Data on how to correctly modify the codepointers
struct CodePointerAlias struct CodePointerAlias
{ {
char name[20]; FName name;
char alias[20]; char alias[20];
BYTE params; BYTE params;
}; };
@ -164,7 +163,7 @@ static TArray<CodePointerAlias> MBFCodePointers;
struct AmmoPerAttack struct AmmoPerAttack
{ {
actionf_p func; VMNativeFunction **func;
int ammocount; int ammocount;
}; };
@ -174,7 +173,7 @@ DECLARE_ACTION(A_FireShotgun)
DECLARE_ACTION(A_FireShotgun2) DECLARE_ACTION(A_FireShotgun2)
DECLARE_ACTION(A_FireCGun) DECLARE_ACTION(A_FireCGun)
DECLARE_ACTION(A_FireMissile) DECLARE_ACTION(A_FireMissile)
DECLARE_ACTION_PARAMS(A_Saw) DECLARE_ACTION(A_Saw)
DECLARE_ACTION(A_FirePlasma) DECLARE_ACTION(A_FirePlasma)
DECLARE_ACTION(A_FireBFG) DECLARE_ACTION(A_FireBFG)
DECLARE_ACTION(A_FireOldBFG) DECLARE_ACTION(A_FireOldBFG)
@ -182,17 +181,17 @@ DECLARE_ACTION(A_FireRailgun)
// Default ammo use of the various weapon attacks // Default ammo use of the various weapon attacks
static AmmoPerAttack AmmoPerAttacks[] = { static AmmoPerAttack AmmoPerAttacks[] = {
{ AF_A_Punch, 0}, { &A_Punch_VMPtr, 0},
{ AF_A_FirePistol, 1}, { &A_FirePistol_VMPtr, 1},
{ AF_A_FireShotgun, 1}, { &A_FireShotgun_VMPtr, 1},
{ AF_A_FireShotgun2, 2}, { &A_FireShotgun2_VMPtr, 2},
{ AF_A_FireCGun, 1}, { &A_FireCGun_VMPtr, 1},
{ AF_A_FireMissile, 1}, { &A_FireMissile_VMPtr, 1},
{ AFP_A_Saw, 0}, { &A_Saw_VMPtr, 0},
{ AF_A_FirePlasma, 1}, { &A_FirePlasma_VMPtr, 1},
{ AF_A_FireBFG, -1}, // uses deh.BFGCells { &A_FireBFG_VMPtr, -1}, // uses deh.BFGCells
{ AF_A_FireOldBFG, 1}, { &A_FireOldBFG_VMPtr, 1},
{ AF_A_FireRailgun, 1}, { &A_FireRailgun_VMPtr, 1},
{ NULL, 0} { NULL, 0}
}; };
@ -232,7 +231,7 @@ IMPLEMENT_POINTY_CLASS (ADehackedPickup)
DECLARE_POINTER (RealPickup) DECLARE_POINTER (RealPickup)
END_POINTERS END_POINTERS
TArray<PClass *> TouchedActors; TArray<PClassActor *> TouchedActors;
char *UnchangedSpriteNames; char *UnchangedSpriteNames;
int NumUnchangedSprites; int NumUnchangedSprites;
@ -354,11 +353,14 @@ static bool ReadChars (char **stuff, int size);
static char *igets (void); static char *igets (void);
static int GetLine (void); static int GetLine (void);
static void PushTouchedActor(PClass *cls) static void PushTouchedActor(PClassActor *cls)
{ {
for(unsigned i = 0; i < TouchedActors.Size(); i++) for(unsigned i = 0; i < TouchedActors.Size(); i++)
{ {
if (TouchedActors[i] == cls) return; if (TouchedActors[i] == cls)
{
return;
}
} }
TouchedActors.Push(cls); TouchedActors.Push(cls);
} }
@ -426,7 +428,7 @@ static FState *FindState (int statenum)
{ {
if (StateMap[i].OwnerIsPickup) if (StateMap[i].OwnerIsPickup)
{ {
PushTouchedActor(const_cast<PClass *>(StateMap[i].Owner)); PushTouchedActor(StateMap[i].Owner);
} }
return StateMap[i].State + statenum - stateacc; 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. // misc1 = vrange (arg +3), misc2 = hrange (arg+4)
enum MBFCodePointers 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 // Die and Detonate are not in this list because these codepointers have
// no dehacked arguments and therefore do not need special handling. // no dehacked arguments and therefore do not need special handling.
// NailBomb has no argument but is implemented as new parameters for A_Explode. // NailBomb has no argument but is implemented as new parameters for A_Explode.
MBF_Mushroom, // misc1 = vrange (arg +3), misc2 = hrange (arg+4) CreateMushroomFunc,
MBF_Spawn, // misc1 = type (arg +0), misc2 = Z-pos (arg +2) CreateSpawnFunc,
MBF_Turn, // misc1 = angle (in degrees) (arg +0 but factor in current actor angle too) CreateTurnFunc,
MBF_Face, // misc1 = angle (in degrees) (arg +0) CreateFaceFunc,
MBF_Scratch, // misc1 = damage, misc 2 = sound CreateScratchFunc,
MBF_PlaySound, // misc1 = sound, misc2 = attenuation none (true) or normal (false) CreatePlaySoundFunc,
MBF_RandomJump, // misc1 = state, misc2 = probability CreateRandomJumpFunc,
MBF_LineEffect, // misc1 = Boom linedef type, misc2 = sector tag CreateLineEffectFunc,
SMMU_NailBomb, // No misc, but it's basically A_Explode with an added effect 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 value1 = state->GetMisc1();
int value2 = state->GetMisc2(); 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. // 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 // Even if the lump was parsed by an FScanner, there would hardly be a way to
// identify which line is troublesome. // 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. // Let's identify the codepointer we're dealing with.
PSymbolActionFunction * sym; PSymbol * s; PFunction *sym;
s = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true); sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
if (!s || s->SymbolType != SYM_ActionFunction) return; if (sym == NULL) return;
sym = static_cast<PSymbolActionFunction*>(s);
if (codepointer < 0 || (unsigned)codepointer >= countof(MBFCodePointerFactories))
// 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)
{ {
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. // This simply should not happen.
Printf("Unmanaged dehacked codepointer alias num %i\n", codepointer); 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) static int PatchThing (int thingy)
@ -785,7 +843,7 @@ static int PatchThing (int thingy)
FStateDefinitions statedef; FStateDefinitions statedef;
bool patchedStates = false; bool patchedStates = false;
ActorFlags oldflags; ActorFlags oldflags;
const PClass *type; PClassActor *type;
SWORD *ednum, dummyed; SWORD *ednum, dummyed;
type = NULL; type = NULL;
@ -811,7 +869,7 @@ static int PatchThing (int thingy)
else else
{ {
info = GetDefaultByType (type); 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) else if (linelen == 14 && stricmp (Line1, "Missile damage") == 0)
{ {
info->Damage = val; info->Damage = CreateDamageFunction(val);
} }
else if (linelen == 5) else if (linelen == 5)
{ {
@ -1227,7 +1285,7 @@ static int PatchThing (int thingy)
if (info->flags & MF_SPECIAL) 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 // 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; info->flags4 |= MF4_CANUSEWALLS;
if (patchedStates) 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) static int PatchAmmo (int ammoNum)
{ {
const PClass *ammoType = NULL; PClassAmmo *ammoType = NULL;
AAmmo *defaultAmmo = NULL; AAmmo *defaultAmmo = NULL;
int result; int result;
int oldclip; int oldclip;
@ -1509,9 +1567,9 @@ static int PatchAmmo (int ammoNum)
// Fix per-ammo/max-ammo amounts for descendants of the base ammo class // Fix per-ammo/max-ammo amounts for descendants of the base ammo class
if (oldclip != *per) 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) if (type == ammoType)
continue; continue;
@ -1543,7 +1601,7 @@ static int PatchAmmo (int ammoNum)
static int PatchWeapon (int weapNum) static int PatchWeapon (int weapNum)
{ {
int result; int result;
const PClass *type = NULL; PClassActor *type = NULL;
BYTE dummy[sizeof(AWeapon)]; BYTE dummy[sizeof(AWeapon)];
AWeapon *info = (AWeapon *)&dummy; AWeapon *info = (AWeapon *)&dummy;
bool patchedStates = false; bool patchedStates = false;
@ -1647,28 +1705,26 @@ static int PatchWeapon (int weapNum)
if (patchedStates) if (patchedStates)
{ {
statedef.InstallStates(type->ActorInfo, info); statedef.InstallStates(type, info);
} }
return result; 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); state->SetAction(NULL);
return; return;
} }
else else
{ {
FString symname = sym->SymbolName.GetChars(); state->SetAction(sym->Variants[0].Implementation);
state->SetAction(static_cast<PSymbolActionFunction*>(sym));
// Note: CompareNoCase() calls stricmp() and therefore returns 0 when they're the same.
for (unsigned int i = 0; i < MBFCodePointers.Size(); i++) for (unsigned int i = 0; i < MBFCodePointers.Size(); i++)
{ {
if (!symname.CompareNoCase(MBFCodePointers[i].name)) if (sym->SymbolName == MBFCodePointers[i].name)
{ {
MBFParamState newstate; MBFParamState newstate;
newstate.state = state; newstate.state = state;
@ -1722,7 +1778,9 @@ static int PatchPointer (int ptrNum)
{ {
int index = atoi(Line2); int index = atoi(Line2);
if ((unsigned)(index) >= Actions.Size()) if ((unsigned)(index) >= Actions.Size())
{
SetPointer(state, NULL); SetPointer(state, NULL);
}
else else
{ {
SetPointer(state, Actions[index], CodePConv[ptrNum]); SetPointer(state, Actions[index], CodePConv[ptrNum]);
@ -1820,16 +1878,16 @@ static int PatchMisc (int dummy)
"Minotaur", "Minotaur",
NULL NULL
}; };
static const PClass * const types[] = static const PClass * const *types[] =
{ {
RUNTIME_CLASS(APowerInvulnerable), &RUNTIME_CLASS_CASTLESS(APowerInvulnerable),
RUNTIME_CLASS(APowerStrength), &RUNTIME_CLASS_CASTLESS(APowerStrength),
RUNTIME_CLASS(APowerInvisibility), &RUNTIME_CLASS_CASTLESS(APowerInvisibility),
RUNTIME_CLASS(APowerIronFeet), &RUNTIME_CLASS_CASTLESS(APowerIronFeet),
RUNTIME_CLASS(APowerLightAmp), &RUNTIME_CLASS_CASTLESS(APowerLightAmp),
RUNTIME_CLASS(APowerWeaponLevel2), &RUNTIME_CLASS_CASTLESS(APowerWeaponLevel2),
RUNTIME_CLASS(APowerSpeed), &RUNTIME_CLASS_CASTLESS(APowerSpeed),
RUNTIME_CLASS(APowerMinotaur) &RUNTIME_CLASS_CASTLESS(APowerMinotaur)
}; };
int i; int i;
@ -1855,7 +1913,7 @@ static int PatchMisc (int dummy)
} }
else if (a > 0) 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), BYTE(clamp(a,0.f,1.f)*255.f),
clamp(r,0,255), clamp(r,0,255),
clamp(g,0,255), clamp(g,0,255),
@ -1863,7 +1921,7 @@ static int PatchMisc (int dummy)
} }
else 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; player->health = deh.StartHealth;
// Hm... I'm not sure that this is the right way to change this info... // 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; DDropItem *di = PClass::FindActor(NAME_DoomPlayer)->DropItems;
if (index >= 0 && index < (signed)DropItemList.Size()) while (di != NULL)
{ {
FDropItem * di = DropItemList[index]; if (di->Name == NAME_Clip)
while (di != NULL)
{ {
if (di->Name == NAME_Clip) di->Amount = deh.StartBullets;
{
di->amount = deh.StartBullets;
}
di = di->Next;
} }
di = di->Next;
} }
} }
@ -2043,21 +2097,21 @@ static int PatchCodePtrs (int dummy)
if (!symname.CompareNoCase(MBFCodePointers[i].alias)) if (!symname.CompareNoCase(MBFCodePointers[i].alias))
{ {
symname = MBFCodePointers[i].name; 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 // This skips the action table and goes directly to the internal symbol table
// DEH compatible functions are easy to recognize. // DEH compatible functions are easy to recognize.
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true); PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true));
if (sym == NULL || sym->SymbolType != SYM_ActionFunction) if (sym == NULL)
{ {
Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2); Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2);
} }
else else
{ {
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments; TArray<DWORD> &args = sym->Variants[0].ArgFlags;
if (args.Len()!=0 && (args[0]<'a' || args[0]>'z')) if (args.Size() != 0 && !(args[0] & VARF_Optional))
{ {
Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2); Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
sym = NULL; sym = NULL;
@ -2541,25 +2595,6 @@ static inline bool CompareLabel (const char *want, const BYTE *have)
return *(DWORD *)want == *(DWORD *)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 int DehUseCount;
static void UnloadDehSupp () static void UnloadDehSupp ()
@ -2680,15 +2715,15 @@ static bool LoadDehSupp ()
// or AActor so this will find all of them. // or AActor so this will find all of them.
FString name = "A_"; FString name = "A_";
name << sc.String; name << sc.String;
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true); PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true));
if (sym == NULL || sym->SymbolType != SYM_ActionFunction) if (sym == NULL)
{ {
sc.ScriptError("Unknown code pointer '%s'", sc.String); sc.ScriptError("Unknown code pointer '%s'", sc.String);
} }
else else
{ {
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments; TArray<DWORD> &args = sym->Variants[0].ArgFlags;
if (args.Len()!=0 && (args[0]<'a' || args[0]>'z')) if (args.Size() != 0 && !(args[0] & VARF_Optional))
{ {
sc.ScriptError("Incompatible code pointer '%s'", sc.String); sc.ScriptError("Incompatible code pointer '%s'", sc.String);
} }
@ -2757,19 +2792,20 @@ static bool LoadDehSupp ()
StateMapper s; StateMapper s;
sc.MustGetString(); sc.MustGetString();
const PClass *type = PClass::FindClass (sc.String); PClass *type = PClass::FindClass (sc.String);
if (type == NULL) if (type == NULL)
{ {
sc.ScriptError ("Can't find type %s", sc.String); 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.MustGetStringName(",");
sc.MustGetString(); 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) if (s.State == NULL)
{ {
sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars()); sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
@ -2777,14 +2813,14 @@ static bool LoadDehSupp ()
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetNumber(); 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()); sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
} }
AActor *def = GetDefaultByType(type); AActor *def = GetDefaultByType(type);
s.StateSpan = sc.Number; s.StateSpan = sc.Number;
s.Owner = type; s.Owner = actortype;
s.OwnerIsPickup = def != NULL && (def->flags & MF_SPECIAL) != 0; s.OwnerIsPickup = def != NULL && (def->flags & MF_SPECIAL) != 0;
if (addit) StateMap.Push(s); if (addit) StateMap.Push(s);
@ -2809,7 +2845,7 @@ static bool LoadDehSupp ()
while (!sc.CheckString("}")) while (!sc.CheckString("}"))
{ {
sc.MustGetString(); sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String); PClassActor *cls = PClass::FindActor(sc.String);
if (cls == NULL) if (cls == NULL)
{ {
sc.ScriptError("Unknown actor type '%s'", sc.String); sc.ScriptError("Unknown actor type '%s'", sc.String);
@ -2876,8 +2912,8 @@ static bool LoadDehSupp ()
} }
else else
{ {
const PClass *cls = PClass::FindClass(sc.String); PClassAmmo *cls = dyn_cast<PClassAmmo>(PClass::FindClass(sc.String));
if (cls == NULL || cls->ParentClass != RUNTIME_CLASS(AAmmo)) if (cls == NULL)
{ {
sc.ScriptError("Unknown ammo type '%s'", sc.String); sc.ScriptError("Unknown ammo type '%s'", sc.String);
} }
@ -2894,12 +2930,12 @@ static bool LoadDehSupp ()
while (!sc.CheckString("}")) while (!sc.CheckString("}"))
{ {
sc.MustGetString(); sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String); PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{ {
sc.ScriptError("Unknown weapon type '%s'", sc.String); sc.ScriptError("Unknown weapon type '%s'", sc.String);
} }
WeaponNames.Push(cls); WeaponNames.Push(static_cast<PClassActor *>(cls));
if (sc.CheckString("}")) break; if (sc.CheckString("}")) break;
sc.MustGetStringName(","); sc.MustGetStringName(",");
} }
@ -2915,8 +2951,7 @@ static bool LoadDehSupp ()
temp.alias[19]=0; temp.alias[19]=0;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
strncpy(temp.name, sc.String, 19); temp.name = sc.String;
temp.name[19]=0;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetNumber(); sc.MustGetNumber();
temp.params = sc.Number; temp.params = sc.Number;
@ -2949,7 +2984,7 @@ void FinishDehPatch ()
for (touchedIndex = 0; touchedIndex < TouchedActors.Size(); ++touchedIndex) for (touchedIndex = 0; touchedIndex < TouchedActors.Size(); ++touchedIndex)
{ {
PClass *type = TouchedActors[touchedIndex]; PClassActor *type = TouchedActors[touchedIndex];
AActor *defaults1 = GetDefaultByType (type); AActor *defaults1 = GetDefaultByType (type);
if (!(defaults1->flags & MF_SPECIAL)) if (!(defaults1->flags & MF_SPECIAL))
{ // We only need to do this for pickups { // 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 // Create a new class that will serve as the actual pickup
char typeNameBuilder[32]; char typeNameBuilder[32];
mysnprintf (typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", touchedIndex); mysnprintf (typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", touchedIndex);
PClass *subclass = RUNTIME_CLASS(ADehackedPickup)->CreateDerivedClass PClassActor *subclass = static_cast<PClassActor *>(RUNTIME_CLASS(ADehackedPickup)->
(typeNameBuilder, sizeof(ADehackedPickup)); CreateDerivedClass(typeNameBuilder, sizeof(ADehackedPickup)));
AActor *defaults2 = GetDefaultByType (subclass); AActor *defaults2 = GetDefaultByType (subclass);
memcpy ((void *)defaults2, (void *)defaults1, sizeof(AActor)); memcpy ((void *)defaults2, (void *)defaults1, sizeof(AActor));
@ -2971,21 +3006,21 @@ void FinishDehPatch ()
if (!type->IsDescendantOf(RUNTIME_CLASS(AInventory))) if (!type->IsDescendantOf(RUNTIME_CLASS(AInventory)))
{ {
// If this is a hacked non-inventory item we must also copy AInventory's special states // 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 // Use the DECORATE replacement feature to redirect all spawns
// of the original class to the new one. // of the original class to the new one.
FActorInfo *old_replacement = type->ActorInfo->Replacement; PClassActor *old_replacement = type->Replacement;
type->ActorInfo->Replacement = subclass->ActorInfo; type->Replacement = subclass;
subclass->ActorInfo->Replacee = type->ActorInfo; subclass->Replacee = type;
// If this actor was already replaced by another actor, copy that // If this actor was already replaced by another actor, copy that
// replacement over to this item. // replacement over to this item.
if (old_replacement != NULL) if (old_replacement != NULL)
{ {
subclass->ActorInfo->Replacement = old_replacement; subclass->Replacement = old_replacement;
} }
DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars()); DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars());
@ -3018,7 +3053,7 @@ void FinishDehPatch ()
TMap<FState*, bool> StateVisited; TMap<FState*, bool> StateVisited;
FState *state = WeaponNames[i]->ActorInfo->FindState(NAME_Fire); FState *state = WeaponNames[i]->FindState(NAME_Fire);
while (state != NULL) while (state != NULL)
{ {
bool *check = StateVisited.CheckKey(state); bool *check = StateVisited.CheckKey(state);
@ -3029,7 +3064,7 @@ void FinishDehPatch ()
StateVisited[state] = true; StateVisited[state] = true;
for(unsigned j = 0; AmmoPerAttacks[j].func != NULL; j++) for(unsigned j = 0; AmmoPerAttacks[j].func != NULL; j++)
{ {
if (state->ActionFunc == AmmoPerAttacks[j].func) if (state->ActionFunc == *AmmoPerAttacks[j].func)
{ {
found = true; found = true;
int use = AmmoPerAttacks[j].ammocount; int use = AmmoPerAttacks[j].ammocount;
@ -3051,7 +3086,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount);
bool ADehackedPickup::TryPickup (AActor *&toucher) bool ADehackedPickup::TryPickup (AActor *&toucher)
{ {
const PClass *type = DetermineType (); PClassActor *type = DetermineType ();
if (type == NULL) if (type == NULL)
{ {
return false; return false;
@ -3125,7 +3160,7 @@ void ADehackedPickup::Destroy ()
Super::Destroy (); Super::Destroy ();
} }
const PClass *ADehackedPickup::DetermineType () PClassActor *ADehackedPickup::DetermineType ()
{ {
// Look at the actor's current sprite to determine what kind of // Look at the actor's current sprite to determine what kind of
// item to pretend to me. // item to pretend to me.
@ -3138,7 +3173,7 @@ const PClass *ADehackedPickup::DetermineType ()
int lex = memcmp (DehSpriteMappings[mid].Sprite, sprites[sprite].name, 4); int lex = memcmp (DehSpriteMappings[mid].Sprite, sprites[sprite].name, 4);
if (lex == 0) if (lex == 0)
{ {
return PClass::FindClass (DehSpriteMappings[mid].ClassName); return PClass::FindActor(DehSpriteMappings[mid].ClassName);
} }
else if (lex < 0) else if (lex < 0)
{ {

View file

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

View file

@ -107,6 +107,8 @@
#include "resourcefiles/resourcefile.h" #include "resourcefiles/resourcefile.h"
#include "r_renderer.h" #include "r_renderer.h"
#include "p_local.h" #include "p_local.h"
#include "autosegs.h"
#include "fragglescript/t_fs.h"
EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Bool, hud_althud)
void DrawHUD(); void DrawHUD();
@ -1930,6 +1932,22 @@ static void SetMapxxFlag()
if (lump_name >= 0 || lump_wad >= 0 || lump_map >= 0) gameinfo.flags |= GI_MAPxx; 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 // Initialize
@ -1958,6 +1976,8 @@ static void D_DoomInit()
// Check response files before coalescing file parameters. // Check response files before coalescing file parameters.
M_FindResponseFile (); M_FindResponseFile ();
atterm(FinalGC);
// Combine different file parameters with their pre-switch bits. // Combine different file parameters with their pre-switch bits.
Args->CollectFiles("-deh", ".deh"); Args->CollectFiles("-deh", ".deh");
Args->CollectFiles("-bex", ".bex"); 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 // D_DoomMain
@ -2241,7 +2246,6 @@ void D_DoomMain (void)
// [RH] Make sure zdoom.pk3 is always loaded, // [RH] Make sure zdoom.pk3 is always loaded,
// as it contains magic stuff we need. // as it contains magic stuff we need.
wad = BaseFileSearch (BASEWAD, NULL, true); wad = BaseFileSearch (BASEWAD, NULL, true);
if (wad == NULL) if (wad == NULL)
{ {
@ -2255,13 +2259,13 @@ void D_DoomMain (void)
// Now that we have the IWADINFO, initialize the autoload ini sections. // Now that we have the IWADINFO, initialize the autoload ini sections.
GameConfig->DoAutoloadSetup(iwad_man); GameConfig->DoAutoloadSetup(iwad_man);
PClass::StaticInit ();
atterm(FinalGC);
// reinit from here // reinit from here
do do
{ {
PClass::StaticInit();
PType::StaticInit();
if (restart) if (restart)
{ {
C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false); C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false);
@ -2409,12 +2413,11 @@ void D_DoomMain (void)
Printf ("ParseTeamInfo: Load team definitions.\n"); Printf ("ParseTeamInfo: Load team definitions.\n");
TeamLibrary.ParseTeamInfo (); TeamLibrary.ParseTeamInfo ();
FActorInfo::StaticInit (); PClassActor::StaticInit ();
// [GRB] Initialize player class list // [GRB] Initialize player class list
SetupPlayerClasses (); SetupPlayerClasses ();
// [RH] Load custom key and weapon settings from WADs // [RH] Load custom key and weapon settings from WADs
D_LoadWadSettings (); D_LoadWadSettings ();
@ -2460,9 +2463,8 @@ void D_DoomMain (void)
FinishDehPatch(); FinishDehPatch();
InitActorNumsFromMapinfo(); InitActorNumsFromMapinfo();
PClassActor::StaticSetActorNums ();
InitSpawnablesFromMapinfo(); InitSpawnablesFromMapinfo();
FActorInfo::StaticSetActorNums ();
//Added by MC: //Added by MC:
bglobal.getspawned.Clear(); bglobal.getspawned.Clear();
argcount = Args->CheckParmList("-bots", &args); 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 C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here
DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods
GC::FullGC(); // perform one final garbage collection before deleting the class data GC::FullGC(); // clean up before taking down the object list.
PClass::ClearRuntimeData(); // clear all runtime generated class data
// 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++; restart++;
PClass::bShutdown = false;
} }
} }
while (1); 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; AActor *actor;
int killcount = 0; int killcount = 0;
@ -2291,7 +2291,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_SUMMONFRIEND2: case DEM_SUMMONFRIEND2:
case DEM_SUMMONFOE2: case DEM_SUMMONFOE2:
{ {
const PClass *typeinfo; PClassActor *typeinfo;
int angle = 0; int angle = 0;
SWORD tid = 0; SWORD tid = 0;
BYTE special = 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); for(i = 0; i < 5; i++) args[i] = ReadLong(stream);
} }
typeinfo = PClass::FindClass (s); typeinfo = PClass::FindActor(s);
if (typeinfo != NULL && typeinfo->ActorInfo != NULL) if (typeinfo != NULL)
{ {
AActor *source = players[player].mo; AActor *source = players[player].mo;
if (source != NULL) if (source != NULL)
@ -2534,7 +2534,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_MORPHEX: case DEM_MORPHEX:
{ {
s = ReadString (stream); 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) if (player == consoleplayer)
{ {
Printf ("%s\n", *msg != '\0' ? msg : "Morph failed."); 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); char *classname = ReadString (stream);
int killcount = 0; 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); killcount = KillAll(cls);
const PClass *cls_rep = cls->GetReplacement(); PClassActor *cls_rep = cls->GetReplacement();
if (cls != cls_rep) if (cls != cls_rep)
{ {
killcount += KillAll(cls_rep); killcount += KillAll(cls_rep);
@ -2589,8 +2589,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
{ {
char *classname = ReadString(stream); char *classname = ReadString(stream);
int removecount = 0; int removecount = 0;
const PClass *cls = PClass::FindClass(classname); PClassActor *cls = PClass::FindActor(classname);
if (cls != NULL && cls->ActorInfo != NULL) if (cls != NULL && cls->IsKindOf(RUNTIME_CLASS(PClassActor)))
{ {
removecount = RemoveClass(cls); removecount = RemoveClass(cls);
const PClass *cls_rep = cls->GetReplacement(); 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) 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); players[pnum].weapons.AddSlot(slot, wpn, pnum == consoleplayer);
} }
} }
@ -2642,7 +2642,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_ADDSLOT: case DEM_ADDSLOT:
{ {
int slot = ReadByte(stream); int slot = ReadByte(stream);
const PClass *wpn = Net_ReadWeapon(stream); PClassWeapon *wpn = Net_ReadWeapon(stream);
players[player].weapons.AddSlot(slot, wpn, player == consoleplayer); players[player].weapons.AddSlot(slot, wpn, player == consoleplayer);
} }
break; break;
@ -2650,7 +2650,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_ADDSLOTDEFAULT: case DEM_ADDSLOTDEFAULT:
{ {
int slot = ReadByte(stream); int slot = ReadByte(stream);
const PClass *wpn = Net_ReadWeapon(stream); PClassWeapon *wpn = Net_ReadWeapon(stream);
players[player].weapons.AddSlotDefault(slot, wpn, player == consoleplayer); players[player].weapons.AddSlotDefault(slot, wpn, player == consoleplayer);
} }
break; break;

View file

@ -154,9 +154,9 @@ int D_PlayerClassToInt (const char *classname)
{ {
for (unsigned int i = 0; i < PlayerClasses.Size (); ++i) 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; return i;
} }
@ -178,7 +178,7 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet
if (players[player].mo != NULL) 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) if (colorset != NULL)
{ {
@ -723,7 +723,7 @@ void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact)
case NAME_PlayerClass: case NAME_PlayerClass:
*stream += sprintf(*((char **)stream), "\\%s", info->GetPlayerClassNum() == -1 ? "Random" : *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; break;
case NAME_Skin: case NAME_Skin:
@ -925,7 +925,7 @@ void WriteUserInfo(FArchive &arc, userinfo_t &info)
case NAME_PlayerClass: case NAME_PlayerClass:
i = info.GetPlayerClassNum(); i = info.GetPlayerClassNum();
arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->Meta.GetMetaString(APMETA_DisplayName)); arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->DisplayName);
break; break;
default: default:
@ -1014,7 +1014,7 @@ CCMD (playerinfo)
Printf("%20s: %s (%d)\n", "Skin", skins[ui->GetSkin()].name, ui->GetSkin()); 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", "Gender", GenderNames[ui->GetGender()], ui->GetGender());
Printf("%20s: %s (%d)\n", "PlayerClass", 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()); ui->GetPlayerClassNum());
// Print generic info // Print generic info

View file

@ -44,41 +44,61 @@
//Added by MC: //Added by MC:
#include "b_bot.h" #include "b_bot.h"
enum class player_t;
{
APMETA_BASE = 0x95000,
APMETA_DisplayName, // display name (used in menus etc.) // Standard pre-defined skin colors
APMETA_SoundClass, // sound class struct FPlayerColorSet
APMETA_Face, // doom status bar face (when used) {
APMETA_ColorRange, // skin color range struct ExtraRange
APMETA_InvulMode, {
APMETA_HealingRadius, BYTE RangeStart, RangeEnd; // colors to remap
APMETA_Portrait, BYTE FirstColor, LastColor; // colors to map to
APMETA_Hexenarmor0, };
APMETA_Hexenarmor1,
APMETA_Hexenarmor2, FName Name; // Name of this color
APMETA_Hexenarmor3,
APMETA_Hexenarmor4, int Lump; // Lump to read the translation from, otherwise use next 2 fields
APMETA_Slot0, BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation
APMETA_Slot1,
APMETA_Slot2, BYTE RepresentativeColor; // A palette entry representative of this translation,
APMETA_Slot3, // for map arrows and status bar backgrounds and such
APMETA_Slot4, BYTE NumExtraRanges;
APMETA_Slot5, ExtraRange Extra[6];
APMETA_Slot6,
APMETA_Slot7,
APMETA_Slot8,
APMETA_Slot9,
}; };
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum); typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
void P_EnumPlayerColorSets(FName classname, TArray<int> *out); typedef TMap<FName, PalEntry> PainFlashList;
const char *GetPrintableDisplayName(const PClass *cls);
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 class APlayerPawn : public AActor
{ {
DECLARE_CLASS (APlayerPawn, AActor) DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
virtual void Serialize (FArchive &arc); virtual void Serialize (FArchive &arc);
@ -96,9 +116,9 @@ public:
virtual void TweakSpeeds (int &forwardmove, int &sidemove); virtual void TweakSpeeds (int &forwardmove, int &sidemove);
virtual void MorphPlayerThink (); virtual void MorphPlayerThink ();
virtual void ActivateMorphWeapon (); virtual void ActivateMorphWeapon ();
AWeapon *PickNewWeapon (const PClass *ammotype); AWeapon *PickNewWeapon (PClassAmmo *ammotype);
AWeapon *BestWeapon (const PClass *ammotype); AWeapon *BestWeapon (PClassAmmo *ammotype);
void CheckWeaponSwitch(const PClass *ammotype); void CheckWeaponSwitch(PClassAmmo *ammotype);
virtual void GiveDeathmatchInventory (); virtual void GiveDeathmatchInventory ();
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer); virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
@ -140,7 +160,8 @@ public:
fixed_t AttackZOffset; // attack height, relative to player center fixed_t AttackZOffset; // attack height, relative to player center
fixed_t UseRange; // [NS] Distance at which player can +use fixed_t UseRange; // [NS] Distance at which player can +use
fixed_t AirCapacity; // Multiplier for air supply underwater. fixed_t AirCapacity; // Multiplier for air supply underwater.
const PClass *FlechetteType; PClassActor *FlechetteType;
// [CW] Fades for when you are being damaged. // [CW] Fades for when you are being damaged.
PalEntry DamageFade; PalEntry DamageFade;
@ -251,7 +272,7 @@ public:
bool CheckSkin (int skin); bool CheckSkin (int skin);
const PClass *Type; PClassPlayerPawn *Type;
DWORD Flags; DWORD Flags;
TArray<int> Skins; TArray<int> Skins;
}; };
@ -319,7 +340,7 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{ {
return *static_cast<FIntCVar *>(*CheckKey(NAME_PlayerClass)); return *static_cast<FIntCVar *>(*CheckKey(NAME_PlayerClass));
} }
const PClass *GetPlayerClassType() const PClassPlayerPawn *GetPlayerClassType() const
{ {
return PlayerClasses[GetPlayerClassNum()].Type; return PlayerClasses[GetPlayerClassNum()].Type;
} }
@ -376,7 +397,7 @@ public:
userinfo_t userinfo; // [RH] who is this? 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 DesiredFOV; // desired field of vision
float FOV; // current field of vision float FOV; // current field of vision
@ -434,9 +455,9 @@ public:
short fixedlightlevel; short fixedlightlevel;
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
int morphTics; // player is a chicken/pig if > 0 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 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 TObjPtr<AWeapon> PremorphWeapon; // ready weapon before morphing
int chickenPeck; // chicken peck countdown int chickenPeck; // chicken peck countdown
int jumpTics; // delay the next jump for a moment int jumpTics; // delay the next jump for a moment

View file

@ -364,9 +364,9 @@ void FDecalLib::ReadAllDecals ()
ReadDecals (sc); ReadDecals (sc);
} }
// Supporting code to allow specifying decals directly in the DECORATE lump // 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)); FName v = ENamedName(intptr_t(def->DecalGenerator));
if (v.IsValidName()) if (v.IsValidName())
@ -601,7 +601,7 @@ void FDecalLib::ParseDecalGroup (FScanner &sc)
void FDecalLib::ParseGenerator (FScanner &sc) void FDecalLib::ParseGenerator (FScanner &sc)
{ {
const PClass *type; PClassActor *type;
FDecalBase *decal; FDecalBase *decal;
bool optional = false; bool optional = false;
@ -610,8 +610,8 @@ void FDecalLib::ParseGenerator (FScanner &sc)
optional = sc.Compare("optional"); optional = sc.Compare("optional");
if (optional) sc.MustGetString(); if (optional) sc.MustGetString();
type = PClass::FindClass (sc.String); type = PClass::FindActor (sc.String);
if (type == NULL || type->ActorInfo == NULL) if (type == NULL)
{ {
if (!optional) sc.ScriptError ("%s is not an actor.", sc.String); if (!optional) sc.ScriptError ("%s is not an actor.", sc.String);
} }

View file

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

View file

@ -49,146 +49,18 @@
#include "dsectoreffect.h" #include "dsectoreffect.h"
#include "farchive.h" #include "farchive.h"
PClass DObject::_StaticType;
ClassReg DObject::RegistrationInfo = ClassReg DObject::RegistrationInfo =
{ {
&DObject::_StaticType, // MyClass NULL, // MyClass
"DObject", // Name "DObject", // Name
NULL, // ParentType NULL, // ParentType
sizeof(DObject), // SizeOf
NULL, // Pointers NULL, // Pointers
&DObject::InPlaceConstructor // ConstructNative &DObject::InPlaceConstructor, // ConstructNative
sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum
}; };
_DECLARE_TI(DObject) _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) CCMD (dumpactors)
{ {
const char *const filters[32] = const char *const filters[32] =
@ -200,19 +72,26 @@ CCMD (dumpactors)
"25:DoomStrifeChex", "26:HereticStrifeChex", "27:NotHexen", "28:HexenStrifeChex", "29:NotHeretic", "25:DoomStrifeChex", "26:HereticStrifeChex", "27:NotHexen", "28:HexenStrifeChex", "29:NotHeretic",
"30:NotDoom", "31:All", "30:NotDoom", "31:All",
}; };
Printf("%i object class types total\nActor\tEd Num\tSpawnID\tFilter\tSource\n", PClass::m_Types.Size()); Printf("%i object class types total\nActor\tEd Num\tSpawnID\tFilter\tSource\n", PClass::AllClasses.Size());
for (unsigned int i = 0; i < PClass::m_Types.Size(); i++) for (unsigned int i = 0; i < PClass::AllClasses.Size(); i++)
{ {
PClass *cls = PClass::m_Types[i]; PClass *cls = PClass::AllClasses[i];
if (cls != NULL && cls->ActorInfo != NULL) PClassActor *acls = dyn_cast<PClassActor>(cls);
if (acls != NULL)
{
Printf("%s\t%i\t%i\t%s\t%s\n", Printf("%s\t%i\t%i\t%s\t%s\n",
cls->TypeName.GetChars(), cls->ActorInfo->DoomEdNum, acls->TypeName.GetChars(), acls->DoomEdNum,
cls->ActorInfo->SpawnID, filters[cls->ActorInfo->GameFilter & 31], acls->SpawnID, filters[acls->GameFilter & 31],
cls->Meta.GetMetaString (ACMETA_Lump)); acls->SourceLumpName.GetChars());
}
else if (cls != NULL) else if (cls != NULL)
{
Printf("%s\tn/a\tn/a\tn/a\tEngine (not an actor type)\n", cls->TypeName.GetChars()); Printf("%s\tn/a\tn/a\tn/a\tEngine (not an actor type)\n", cls->TypeName.GetChars());
}
else else
{
Printf("Type %i is not an object class\n", i); Printf("Type %i is not an object class\n", i);
}
} }
} }
@ -323,7 +202,6 @@ CCMD (dumpclasses)
int shown, omitted; int shown, omitted;
DumpInfo *tree = NULL; DumpInfo *tree = NULL;
const PClass *root = NULL; const PClass *root = NULL;
bool showall = true;
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
@ -333,24 +211,14 @@ CCMD (dumpclasses)
Printf ("Class '%s' not found\n", argv[1]); Printf ("Class '%s' not found\n", argv[1]);
return; return;
} }
if (stricmp (argv[1], "Actor") == 0)
{
if (argv.argc() < 3 || stricmp (argv[2], "all") != 0)
{
showall = false;
}
}
} }
shown = omitted = 0; shown = omitted = 0;
DumpInfo::AddType (&tree, root != NULL ? root : RUNTIME_CLASS(DObject)); 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]; PClass *cls = PClass::AllClasses[i];
if (root == NULL || if (root == NULL || cls == root || cls->IsDescendantOf(root))
(cls->IsDescendantOf (root) &&
(showall || cls == root ||
cls->ActorInfo != root->ActorInfo)))
{ {
DumpInfo::AddType (&tree, cls); DumpInfo::AddType (&tree, cls);
// Printf (" %s\n", PClass::m_Types[i]->Name + 1); // Printf (" %s\n", PClass::m_Types[i]->Name + 1);
@ -389,7 +257,7 @@ DObject::DObject (PClass *inClass)
DObject::~DObject () DObject::~DObject ()
{ {
if (!(ObjectFlags & OF_Cleanup)) if (!(ObjectFlags & OF_Cleanup) && !PClass::bShutdown)
{ {
DObject **probe; DObject **probe;
PClass *type = GetClass(); PClass *type = GetClass();
@ -487,9 +355,12 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
int i; int i;
// Go through all objects. // Go through all objects.
i = 0;DObject *last=0;
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext) for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
{ {
i++;
changed += probe->PointerSubstitution(old, notOld); changed += probe->PointerSubstitution(old, notOld);
last = probe;
} }
// Go through the bodyque. // Go through the bodyque.
@ -549,23 +420,33 @@ void DObject::SerializeUserVars(FArchive &arc)
// Write all user variables. // Write all user variables.
for (; symt != NULL; symt = symt->ParentSymbolTable) for (; symt != NULL; symt = symt->ParentSymbolTable)
{ {
for (unsigned i = 0; i < symt->Symbols.Size(); ++i) PSymbolTable::MapType::Iterator it(symt->Symbols);
{ PSymbolTable::MapType::Pair *pair;
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);
arc << var->SymbolName; while (it.NextPair(pair))
arc.WriteCount(count); {
for (j = 0; j < count; ++j) PField *var = dyn_cast<PField>(pair->Value);
{ if (var != NULL && !(var->Flags & VARF_Native))
arc << varloc[j]; {
} 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; arc << varname;
while (varname != NAME_None) while (varname != NAME_None)
{ {
PSymbol *sym = symt->FindSymbol(varname, true); PField *var = dyn_cast<PField>(symt->FindSymbol(varname, true));
DWORD wanted = 0; DWORD wanted = 0;
if (sym != NULL && sym->SymbolType == SYM_Variable) if (var != NULL && !(var->Flags & VARF_Native))
{ {
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym); PType *type = var->Type;
PArray *arraytype = dyn_cast<PArray>(type);
if (var->bUserVar) if (arraytype != NULL)
{ {
wanted = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1; wanted = arraytype->ElementCount;
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset); type = arraytype->ElementType;
} }
else
{
wanted = 1;
}
assert(type == TypeSInt32);
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->Offset);
} }
count = arc.ReadCount(); count = arc.ReadCount();
for (j = 0; j < MIN(wanted, count); ++j) for (j = 0; j < MIN(wanted, count); ++j)

View file

@ -37,7 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "doomtype.h" #include "doomtype.h"
struct PClass; class PClass;
class FArchive; class FArchive;
@ -78,89 +78,68 @@ class DFloorWaggle;
class DPlat; class DPlat;
class DPillar; 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 CLASSREG_PClass,
META_Fixed, // A fixed point number CLASSREG_PClassActor,
META_String, // A string 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 struct ClassReg
{ {
PClass *MyClass; PClass *MyClass;
const char *Name; const char *Name;
PClass *ParentType; ClassReg *ParentType;
unsigned int SizeOf;
const size_t *Pointers; const size_t *Pointers;
void (*ConstructNative)(void *); void (*ConstructNative)(void *);
unsigned int SizeOf:28;
unsigned int MetaClassNum:4;
void RegisterClass() const; PClass *RegisterClass();
void SetupClass(PClass *cls);
}; };
enum EInPlace { EC_InPlace }; enum EInPlace { EC_InPlace };
#define DECLARE_ABSTRACT_CLASS(cls,parent) \ #define DECLARE_ABSTRACT_CLASS(cls,parent) \
public: \ public: \
static PClass _StaticType; \ virtual PClass *StaticType() const; \
virtual PClass *StaticType() const { return &_StaticType; } \ static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \
static ClassReg RegistrationInfo, *RegistrationInfoPtr; \
private: \ private: \
typedef parent Super; \ typedef parent Super; \
typedef cls ThisClass; 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) \ #define DECLARE_CLASS(cls,parent) \
DECLARE_ABSTRACT_CLASS(cls,parent) \ DECLARE_ABSTRACT_CLASS(cls,parent) \
private: static void InPlaceConstructor (void *mem); 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 \ #define HAS_OBJECT_POINTERS \
static const size_t PointerOffsets[]; static const size_t PointerOffsets[];
@ -170,23 +149,23 @@ private: \
#define END_POINTERS ~(size_t)0 }; #define END_POINTERS ~(size_t)0 };
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma data_seg(".creg$u") # pragma section(".creg$u",read)
# pragma data_seg() # define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg * const cls::RegistrationInfoPtr = &cls::RegistrationInfo;
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg *cls::RegistrationInfoPtr = &cls::RegistrationInfo;
#else #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 #endif
#define _IMP_PCLASS(cls,ptrs,create) \ #define _IMP_PCLASS(cls,ptrs,create) \
PClass cls::_StaticType; \
ClassReg cls::RegistrationInfo = {\ ClassReg cls::RegistrationInfo = {\
RUNTIME_CLASS(cls), \ NULL, \
#cls, \ #cls, \
RUNTIME_CLASS(cls::Super), \ &cls::Super::RegistrationInfo, \
sizeof(cls), \
ptrs, \ ptrs, \
create }; \ create, \
_DECLARE_TI(cls) sizeof(cls), \
cls::MetaClassNum }; \
_DECLARE_TI(cls) \
PClass *cls::StaticType() const { return RegistrationInfo.MyClass; }
#define _IMP_CREATE_OBJ(cls) \ #define _IMP_CREATE_OBJ(cls) \
void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; }
@ -207,7 +186,6 @@ private: \
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \ _IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
const size_t cls::PointerOffsets[] = { const size_t cls::PointerOffsets[] = {
enum EObjectFlags enum EObjectFlags
{ {
// GC flags // GC flags
@ -227,6 +205,7 @@ enum EObjectFlags
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list 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; template<class T> class TObjPtr;
@ -268,6 +247,9 @@ namespace GC
// Size of GC steps. // Size of GC steps.
extern int StepMul; extern int StepMul;
// Is this the final collection just before exit?
extern bool FinalGC;
// Current white value for known-dead objects. // Current white value for known-dead objects.
static inline uint32 OtherWhite() static inline uint32 OtherWhite()
{ {
@ -319,6 +301,9 @@ namespace GC
// is NULLed instead. // is NULLed instead.
void Mark(DObject **obj); void Mark(DObject **obj);
// Marks an array of objects.
void MarkArray(DObject **objs, size_t count);
// For cleanup // For cleanup
void DelSoftRootHead(); void DelSoftRootHead();
@ -340,6 +325,15 @@ namespace GC
obj = t; obj = t;
} }
template<class T> void Mark(TObjPtr<T> &obj); 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 // 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 class DObject
{ {
public: public:
static PClass _StaticType; virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
virtual PClass *StaticType() const { return &_StaticType; } static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
static ClassReg RegistrationInfo, *RegistrationInfoPtr;
static void InPlaceConstructor (void *mem); static void InPlaceConstructor (void *mem);
typedef PClass MetaClass;
private: private:
typedef DObject ThisClass; typedef DObject ThisClass;
protected:
enum { MetaClassNum = CLASSREG_PClass };
// Per-instance variables. There are four. // Per-instance variables. There are four.
private: private:
@ -466,6 +462,10 @@ public:
void SerializeUserVars(FArchive &arc); void SerializeUserVars(FArchive &arc);
virtual void Serialize (FArchive &arc); virtual void Serialize (FArchive &arc);
void ClearClass()
{
Class = NULL;
}
// For catching Serialize functions in derived classes // For catching Serialize functions in derived classes
// that don't call their base class. // that don't call their base class.
@ -601,4 +601,18 @@ inline bool DObject::IsA (const PClass *type) const
return (type == GetClass()); 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__ #endif //__DOBJECT_H__

View file

@ -71,6 +71,7 @@
#include "doomstat.h" #include "doomstat.h"
#include "m_argv.h" #include "m_argv.h"
#include "po_man.h" #include "po_man.h"
#include "autosegs.h"
#include "v_video.h" #include "v_video.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "intermission/intermission.h" #include "intermission/intermission.h"
@ -150,6 +151,7 @@ int Pause = DEFAULT_GCPAUSE;
int StepMul = DEFAULT_GCMUL; int StepMul = DEFAULT_GCMUL;
int StepCount; int StepCount;
size_t Dept; size_t Dept;
bool FinalGC;
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // 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 // MarkRoot
@ -336,6 +354,25 @@ static void MarkRoot()
} }
Mark(SectorMarker); Mark(SectorMarker);
Mark(interpolator.Head); 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 bot stuff.
Mark(bglobal.firstthing); Mark(bglobal.firstthing);
Mark(bglobal.body1); Mark(bglobal.body1);
@ -365,7 +402,7 @@ static void MarkRoot()
// //
// Atomic // 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. // 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 #endif
#include "thingdef/thingdef_type.h" #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 ------------------------------------------------------- // Symbol information -------------------------------------------------------
enum ESymbolType class PSymbol : public DObject
{
SYM_Const,
SYM_Variable,
SYM_ActionFunction
};
struct PSymbol
{ {
DECLARE_ABSTRACT_CLASS(PSymbol, DObject);
public:
virtual ~PSymbol(); virtual ~PSymbol();
ESymbolType SymbolType;
FName SymbolName; FName SymbolName;
protected: protected:
PSymbol(FName name, ESymbolType type) { SymbolType = type; SymbolName = name; } PSymbol(FName name) { 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) {}
}; };
// An action function ------------------------------------------------------- // 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 FState;
struct StateCallData; 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; DECLARE_CLASS(PSymbolVMFunction, PSymbol);
actionf_p Function; HAS_OBJECT_POINTERS;
int defaultparameterindex; 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 ----------------------------------------------------------- // A symbol table -----------------------------------------------------------
class PSymbolTable struct PSymbolTable
{ {
public: PSymbolTable();
PSymbolTable() : ParentSymbolTable(NULL) PSymbolTable(PSymbolTable *parent);
{
}
~PSymbolTable(); ~PSymbolTable();
size_t MarkSymbols();
// Sets the table to use for searches if this one doesn't contain the // Sets the table to use for searches if this one doesn't contain the
// requested symbol. // requested symbol.
void SetParentTable (PSymbolTable *parent); void SetParentTable (PSymbolTable *parent);
@ -112,49 +95,549 @@ public:
void ReleaseSymbols(); void ReleaseSymbols();
private: private:
typedef TMap<FName, PSymbol *> MapType;
PSymbolTable *ParentSymbolTable; PSymbolTable *ParentSymbolTable;
TArray<PSymbol *> Symbols; MapType Symbols;
friend class DObject; 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 --------------------------- // Meta-info for every class derived from DObject ---------------------------
struct PClass class PClassClass;
class PClass : public PStruct
{ {
static void StaticInit (); DECLARE_CLASS(PClass, PStruct);
static void StaticShutdown (); HAS_OBJECT_POINTERS;
static void StaticFreeData (PClass *type); protected:
static void ClearRuntimeData(); 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 ------------------------------------- // Per-class information -------------------------------------
FName TypeName; // this class's name
unsigned int Size; // this class's size
PClass *ParentClass; // the class this class derives from PClass *ParentClass; // the class this class derives from
const size_t *Pointers; // object pointers defined by this class *only* 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 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; BYTE *Defaults;
bool bRuntimeClass; // class was defined at run-time, not compile-time bool bRuntimeClass; // class was defined at run-time, not compile-time
unsigned short ClassIndex;
PSymbolTable Symbols;
void (*ConstructNative)(void *); void (*ConstructNative)(void *);
// The rest are all functions and static data ---------------- // The rest are all functions and static data ----------------
void InsertIntoHash (); PClass();
DObject *CreateNew () const; ~PClass();
PClass *CreateDerivedClass (FName name, unsigned int size); void InsertIntoHash();
DObject *CreateNew() const;
PClass *CreateDerivedClass(FName name, unsigned int size);
unsigned int Extend(unsigned int extension); unsigned int Extend(unsigned int extension);
void InitializeActorInfo (); void InitializeActorInfo();
void BuildFlatPointers (); void BuildFlatPointers();
void FreeStateList();
const PClass *NativeClass() const; const PClass *NativeClass() const;
// Returns true if this type is an ancestor of (or same as) the passed type. // 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) while (ti)
{ {
@ -164,26 +647,160 @@ struct PClass
} }
return false; 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. // Find a type, given its name.
static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); } static PClass *FindClass(const char *name) { return FindClass(FName(name, true)); }
static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); } static PClass *FindClass(const FString &name) { return FindClass(FName(name, true)); }
static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); } static PClass *FindClass(ENamedName name) { return FindClass(FName(name)); }
static const PClass *FindClass (FName name); static PClass *FindClass(FName name);
const PClass *FindClassTentative (FName name); // not static! static PClassActor *FindActor(const char *name) { return FindActor(FName(name, true)); }
PClass *GetReplacement() const; 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 *> AllClasses;
static TArray<PClass *> m_RuntimeActors;
enum { HASH_SIZE = 256 };
static PClass *TypeHash[HASH_SIZE];
static bool bShutdown; 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 #endif

View file

@ -46,8 +46,8 @@
#include "zstring.h" #include "zstring.h"
#include "vectors.h" #include "vectors.h"
struct PClass; class PClassActor;
typedef TMap<int, const PClass *> FClassMap; typedef TMap<int, PClassActor *> FClassMap;
// Since this file is included by everything, it seems an appropriate place // Since this file is included by everything, it seems an appropriate place
// to check the NOASM/USEASM macros. // to check the NOASM/USEASM macros.

View file

@ -43,6 +43,7 @@
static cycle_t ThinkCycles; static cycle_t ThinkCycles;
extern cycle_t BotSupportCycles; extern cycle_t BotSupportCycles;
extern cycle_t ActionCycles;
extern int BotWTG; extern int BotWTG;
IMPLEMENT_CLASS (DThinker) IMPLEMENT_CLASS (DThinker)
@ -406,6 +407,7 @@ void DThinker::RunThinkers ()
ThinkCycles.Reset(); ThinkCycles.Reset();
BotSupportCycles.Reset(); BotSupportCycles.Reset();
ActionCycles.Reset();
BotWTG = 0; BotWTG = 0;
ThinkCycles.Clock(); ThinkCycles.Clock();
@ -573,6 +575,6 @@ DThinker *FThinkerIterator::Next ()
ADD_STAT (think) ADD_STAT (think)
{ {
FString out; 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; return out;
} }

View file

@ -121,10 +121,10 @@ public:
template <class T> class TThinkerIterator : public FThinkerIterator template <class T> class TThinkerIterator : public FThinkerIterator
{ {
public: 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) 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) void FArchive::AttachToFile (FFile &file)
{ {
unsigned int i;
m_HubTravel = false; m_HubTravel = false;
m_File = &file; m_File = &file;
m_MaxObjectCount = m_ObjectCount = 0;
m_ObjectMap = NULL;
if (file.Mode() == FFile::EReading) if (file.Mode() == FFile::EReading)
{ {
m_Loading = true; m_Loading = true;
@ -679,19 +675,17 @@ void FArchive::AttachToFile (FFile &file)
m_Storing = true; m_Storing = true;
} }
m_Persistent = file.IsPersistent(); m_Persistent = file.IsPersistent();
m_TypeMap = NULL;
m_TypeMap = new TypeMap[PClass::m_Types.Size()]; ClassToArchive.Clear();
for (i = 0; i < PClass::m_Types.Size(); i++) ArchiveToClass.Clear();
{
m_TypeMap[i].toArchive = TypeMap::NO_INDEX; ObjectToArchive.Clear();
m_TypeMap[i].toCurrent = NULL; ArchiveToObject.Clear();
}
m_ClassCount = 0; memset(m_NameHash, 0xFF, sizeof(m_NameHash));
for (i = 0; i < EObjectHashSize; i++) m_Names.Clear();
{ m_NameStorage.Clear();
m_ObjectHash[i] = ~0;
m_NameHash[i] = NameMap::NO_INDEX;
}
m_NumSprites = 0; m_NumSprites = 0;
m_SpriteMap = new int[sprites.Size()]; m_SpriteMap = new int[sprites.Size()];
for (size_t s = 0; s < sprites.Size(); ++s) for (size_t s = 0; s < sprites.Size(); ++s)
@ -703,10 +697,6 @@ void FArchive::AttachToFile (FFile &file)
FArchive::~FArchive () FArchive::~FArchive ()
{ {
Close (); Close ();
if (m_TypeMap)
delete[] m_TypeMap;
if (m_ObjectMap)
M_Free (m_ObjectMap);
if (m_SpriteMap) if (m_SpriteMap)
delete[] m_SpriteMap; delete[] m_SpriteMap;
} }
@ -727,7 +717,7 @@ void FArchive::Close ()
{ {
m_File->Close (); m_File->Close ();
m_File = NULL; 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) FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
{ {
if (IsStoring ()) if (!type->IsDescendantOf(RUNTIME_CLASS(PClass)))
{ { // a regular object
return WriteObject (object); if (IsStoring())
{
return WriteObject(object);
}
else
{
return ReadObject(object, type);
}
} }
else else
{ { // a class object
return ReadObject (object, type); if (IsStoring())
{
UserWriteClass((PClass *)object);
}
else
{
UserReadClass(object);
}
return *this;
} }
} }
@ -1068,7 +1073,8 @@ FArchive &FArchive::WriteObject (DObject *obj)
} }
else else
{ {
const PClass *type = RUNTIME_TYPE(obj); PClass *type = obj->GetClass();
DWORD *classarcid;
if (type == RUNTIME_CLASS(DObject)) if (type == RUNTIME_CLASS(DObject))
{ {
@ -1077,7 +1083,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
id[0] = NULL_OBJ; id[0] = NULL_OBJ;
Write (id, 1); 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. // No instances of this class have been written out yet.
// Write out the class, then write out the object. If this // 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 // to the saved object. Otherwise, save a reference to the
// class, then save the object. Again, if this is a player- // class, then save the object. Again, if this is a player-
// controlled actor, remember that. // 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)) && if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
@ -1128,7 +1134,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
id[0] = NEW_OBJ; id[0] = NEW_OBJ;
Write (id, 1); Write (id, 1);
} }
WriteCount (m_TypeMap[type->ClassIndex].toArchive); WriteCount (*classarcid);
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell()); // Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
MapObject (obj); MapObject (obj);
obj->SerializeUserVars (*this); obj->SerializeUserVars (*this);
@ -1139,7 +1145,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
{ {
id[0] = OLD_OBJ; id[0] = OLD_OBJ;
Write (id, 1); Write (id, 1);
WriteCount (index); WriteCount (*objarcid);
} }
} }
} }
@ -1166,12 +1172,12 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
break; break;
case OLD_OBJ: case OLD_OBJ:
index = ReadCount (); index = ReadCount();
if (index >= m_ObjectCount) 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; break;
case NEW_PLYR_CLS_OBJ: case NEW_PLYR_CLS_OBJ:
@ -1386,24 +1392,19 @@ DWORD FArchive::FindName (const char *name, unsigned int bucket) const
return (DWORD)map; return (DWORD)map;
} }
DWORD FArchive::WriteClass (const PClass *info) DWORD FArchive::WriteClass (PClass *info)
{ {
if (m_ClassCount >= PClass::m_Types.Size()) if (ClassToArchive.CheckKey(info) != NULL)
{
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)
{ {
I_Error ("Attempt to write '%s' twice.\n", info->TypeName.GetChars()); I_Error ("Attempt to write '%s' twice.\n", info->TypeName.GetChars());
} }
m_TypeMap[info->ClassIndex].toArchive = m_ClassCount; DWORD index = ArchiveToClass.Push(info);
m_TypeMap[m_ClassCount].toCurrent = info; ClassToArchive[info] = index;
WriteString (info->TypeName.GetChars()); WriteString (info->TypeName.GetChars());
return m_ClassCount++; return index;
} }
const PClass *FArchive::ReadClass () PClass *FArchive::ReadClass ()
{ {
struct String { struct String {
String() { val = NULL; } String() { val = NULL; }
@ -1411,33 +1412,24 @@ const PClass *FArchive::ReadClass ()
char *val; char *val;
} typeName; } 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); operator<< (typeName.val);
FName zaname(typeName.val, true); FName zaname(typeName.val, true);
if (zaname != NAME_None) 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) ClassToArchive[type] = ArchiveToClass.Push(type);
{ return type;
m_TypeMap[i].toArchive = m_ClassCount;
m_TypeMap[m_ClassCount].toCurrent = PClass::m_Types[i];
m_ClassCount++;
return PClass::m_Types[i];
}
} }
} }
I_Error ("Unknown class '%s'\n", typeName.val); I_Error ("Unknown class '%s'\n", typeName.val);
return NULL; 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)) if (!type->IsDescendantOf (wanttype))
{ {
I_Error ("Expected to extract an object of type '%s'.\n" I_Error ("Expected to extract an object of type '%s'.\n"
@ -1447,14 +1439,10 @@ const PClass *FArchive::ReadClass (const PClass *wanttype)
return type; return type;
} }
const PClass *FArchive::ReadStoredClass (const PClass *wanttype) PClass *FArchive::ReadStoredClass (const PClass *wanttype)
{ {
DWORD index = ReadCount (); DWORD index = ReadCount ();
if (index >= m_ClassCount) PClass *type = ArchiveToClass[index];
{
I_Error ("Class reference too high (%u; max is %u)\n", index, m_ClassCount);
}
const PClass *type = m_TypeMap[index].toCurrent;
if (!type->IsDescendantOf (wanttype)) if (!type->IsDescendantOf (wanttype))
{ {
I_Error ("Expected to extract an object of type '%s'.\n" I_Error ("Expected to extract an object of type '%s'.\n"
@ -1464,47 +1452,14 @@ const PClass *FArchive::ReadStoredClass (const PClass *wanttype)
return type; return type;
} }
DWORD FArchive::MapObject (const DObject *obj) DWORD FArchive::MapObject (DObject *obj)
{ {
DWORD i; DWORD i = ArchiveToObject.Push(obj);
ObjectToArchive[obj] = i;
if (m_ObjectCount >= m_MaxObjectCount) return i;
{
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 FArchive::HashObject (const DObject *obj) const void FArchive::UserWriteClass (PClass *type)
{
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)
{ {
BYTE id; BYTE id;
@ -1515,7 +1470,8 @@ void FArchive::UserWriteClass (const PClass *type)
} }
else else
{ {
if (m_TypeMap[type->ClassIndex].toArchive == TypeMap::NO_INDEX) DWORD *arcid;
if (NULL == (arcid = ClassToArchive.CheckKey(type)))
{ {
id = 1; id = 1;
Write (&id, 1); Write (&id, 1);
@ -1525,12 +1481,12 @@ void FArchive::UserWriteClass (const PClass *type)
{ {
id = 0; id = 0;
Write (&id, 1); Write (&id, 1);
WriteCount (m_TypeMap[type->ClassIndex].toArchive); WriteCount (*arcid);
} }
} }
} }
void FArchive::UserReadClass (const PClass *&type) void FArchive::UserReadClass (PClass *&type)
{ {
BYTE newclass; 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) FArchive &operator<< (FArchive &arc, sector_t *&sec)
{ {
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors)); 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); void WriteCount (DWORD count);
DWORD ReadCount (); DWORD ReadCount ();
void UserWriteClass (const PClass *info); void UserWriteClass (PClass *info);
void UserReadClass (const 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<< (BYTE &c);
FArchive& operator<< (WORD &s); FArchive& operator<< (WORD &s);
@ -206,13 +212,11 @@ inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUN
protected: protected:
enum { EObjectHashSize = 137 }; enum { EObjectHashSize = 137 };
DWORD FindObjectIndex (const DObject *obj) const; DWORD MapObject (DObject *obj);
DWORD MapObject (const DObject *obj); DWORD WriteClass (PClass *info);
DWORD WriteClass (const PClass *info); PClass *ReadClass ();
const PClass *ReadClass (); PClass *ReadClass (const PClass *wanttype);
const PClass *ReadClass (const PClass *wanttype); PClass *ReadStoredClass (const PClass *wanttype);
const PClass *ReadStoredClass (const PClass *wanttype);
DWORD HashObject (const DObject *obj) const;
DWORD AddName (const char *name); DWORD AddName (const char *name);
DWORD AddName (unsigned int start); // Name has already been added to storage DWORD AddName (unsigned int start); // Name has already been added to storage
DWORD FindName (const char *name) const; DWORD FindName (const char *name) const;
@ -223,24 +227,12 @@ protected:
bool m_Storing; // inserting objects? bool m_Storing; // inserting objects?
bool m_HubTravel; // travelling inside a hub? bool m_HubTravel; // travelling inside a hub?
FFile *m_File; // unerlying file object 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 TMap<PClass *, DWORD> ClassToArchive; // Maps PClass to archive type index
{ TArray<PClass *> ArchiveToClass; // Maps archive type index to PClass
const PClass *toCurrent; // maps archive type index to execution type index
DWORD toArchive; // maps execution type index to archive type index
enum { NO_INDEX = 0xffffffff }; TMap<DObject *, DWORD> ObjectToArchive; // Maps objects to archive index
} *m_TypeMap; TArray<DObject *> ArchiveToObject; // Maps archive index to objects
struct ObjectMap
{
const DObject *object;
DWORD hashNext;
} *m_ObjectMap;
DWORD m_ObjectHash[EObjectHashSize];
struct NameMap struct NameMap
{ {
@ -281,11 +273,9 @@ inline FArchive &operator<< (FArchive &arc, PalEntry &p)
template<class T> template<class T>
inline FArchive &operator<< (FArchive &arc, T* &object) 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; class FFont;
FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font); FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font);
template<> inline FArchive &operator<< <FFont> (FArchive &arc, FFont* &font) template<> inline FArchive &operator<< <FFont> (FArchive &arc, FFont* &font)

View file

@ -10,5 +10,6 @@ class AActor;
void T_PreprocessScripts(); void T_PreprocessScripts();
void T_LoadScripts(MapData * map); void T_LoadScripts(MapData * map);
void T_AddSpawnedThing(AActor * ); void T_AddSpawnedThing(AActor * );
void FS_Close();
#endif #endif

View file

@ -228,7 +228,7 @@ static const char * const ActorNames_init[]=
"PointPuller", "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 // 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) if (arg.type==svt_string)
{ {
PClass=PClass::FindClass(arg.string); pclass=PClass::FindActor(arg.string);
// invalid object to spawn // 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) else if (arg.type==svt_mobj)
{ {
AActor * mo = actorvalue(arg); AActor * mo = actorvalue(arg);
if (mo) PClass = mo->GetClass(); if (mo) pclass = mo->GetClass();
} }
else else
{ {
int objtype = intvalue(arg); int objtype = intvalue(arg);
if (objtype>=0 && objtype<int(countof(ActorTypes))) PClass=ActorTypes[objtype]; if (objtype>=0 && objtype<int(countof(ActorTypes))) pclass=ActorTypes[objtype];
else PClass=NULL; else pclass=NULL;
// invalid object to spawn // 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 // 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; const char * p;
@ -362,8 +362,8 @@ static const PClass * T_GetAmmo(const svalue_t &t)
} }
p=DefAmmo[ammonum]; p=DefAmmo[ammonum];
} }
const PClass * am=PClass::FindClass(p); PClassAmmo * am=dyn_cast<PClassAmmo>(PClass::FindActor(p));
if (!am->IsDescendantOf(RUNTIME_CLASS(AAmmo))) if (am == NULL)
{ {
script_error("unknown ammo type : %s", p); script_error("unknown ammo type : %s", p);
return NULL; return NULL;
@ -861,12 +861,12 @@ void FParser::SF_Player(void)
void FParser::SF_Spawn(void) void FParser::SF_Spawn(void)
{ {
int x, y, z; int x, y, z;
const PClass *PClass; PClassActor *pclass;
angle_t angle = 0; angle_t angle = 0;
if (CheckArgs(3)) if (CheckArgs(3))
{ {
if (!(PClass=T_GetMobjType(t_argv[0]))) return; if (!(pclass=T_GetMobjType(t_argv[0]))) return;
x = fixedvalue(t_argv[1]); x = fixedvalue(t_argv[1]);
y = fixedvalue(t_argv[2]); y = fixedvalue(t_argv[2]);
@ -892,7 +892,7 @@ void FParser::SF_Spawn(void)
} }
t_return.type = svt_mobj; 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) if (t_return.value.mobj)
{ {
@ -2570,8 +2570,8 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
{ {
type = "BasicArmorPickup"; type = "BasicArmorPickup";
} }
const PClass * info = PClass::FindClass (type); PClassInventory * info = dyn_cast<PClassInventory>(PClass::FindActor (type));
if (info == NULL || !info->IsDescendantOf (RUNTIME_CLASS(AInventory))) if (info == NULL)
{ {
Printf ("Unknown inventory item: %s\n", type); Printf ("Unknown inventory item: %s\n", type);
return; return;
@ -2623,7 +2623,7 @@ static void FS_TakeInventory (AActor *actor, const char * type, int amount)
{ {
return; return;
} }
const PClass * info = PClass::FindClass (type); PClassActor * info = PClass::FindActor (type);
if (info == NULL) if (info == NULL)
{ {
return; return;
@ -2672,7 +2672,7 @@ static int FS_CheckInventory (AActor *activator, const char *type)
return activator->health; return activator->health;
} }
const PClass *info = PClass::FindClass (type); PClassActor *info = PClass::FindActor (type);
AInventory *item = activator->FindInventory (info); AInventory *item = activator->FindInventory (info);
return item ? item->Amount : 0; return item ? item->Amount : 0;
} }
@ -2732,7 +2732,7 @@ void FParser::SF_PlayerKeys(void)
void FParser::SF_PlayerAmmo(void) void FParser::SF_PlayerAmmo(void)
{ {
int playernum, amount; int playernum, amount;
const PClass * ammotype; PClassAmmo * ammotype;
if (CheckArgs(2)) if (CheckArgs(2))
{ {
@ -2768,7 +2768,7 @@ void FParser::SF_PlayerAmmo(void)
void FParser::SF_MaxPlayerAmmo() void FParser::SF_MaxPlayerAmmo()
{ {
int playernum, amount; int playernum, amount;
const PClass * ammotype; PClassAmmo * ammotype;
if (CheckArgs(2)) if (CheckArgs(2))
{ {
@ -2843,7 +2843,7 @@ void FParser::SF_PlayerWeapon()
script_error("weaponnum out of range! %s\n", weaponnum); script_error("weaponnum out of range! %s\n", weaponnum);
return; return;
} }
const PClass * ti = PClass::FindClass(WeaponNames[weaponnum]); PClassWeapon * ti = static_cast<PClassWeapon *>(PClass::FindActor(WeaponNames[weaponnum]));
if (!ti) if (!ti)
{ {
script_error("incompatibility in playerweapon\n", weaponnum); script_error("incompatibility in playerweapon\n", weaponnum);
@ -2924,7 +2924,7 @@ void FParser::SF_PlayerSelectedWeapon()
script_error("weaponnum out of range! %s\n", weaponnum); script_error("weaponnum out of range! %s\n", weaponnum);
return; return;
} }
const PClass * ti = PClass::FindClass(WeaponNames[weaponnum]); PClassWeapon * ti = static_cast<PClassWeapon *>(PClass::FindActor(WeaponNames[weaponnum]));
if (!ti) if (!ti)
{ {
script_error("incompatibility in playerweapon\n", weaponnum); script_error("incompatibility in playerweapon\n", weaponnum);
@ -3028,7 +3028,7 @@ void FParser::SF_SetWeapon()
int playernum=T_GetPlayerNum(t_argv[0]); int playernum=T_GetPlayerNum(t_argv[0]);
if (playernum!=-1) 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))) if (item == NULL || !item->IsKindOf (RUNTIME_CLASS(AWeapon)))
{ {
@ -3343,11 +3343,11 @@ void FParser::SF_SpawnExplosion()
{ {
fixed_t x, y, z; fixed_t x, y, z;
AActor* spawn; AActor* spawn;
const PClass * PClass; PClassActor * pclass;
if (CheckArgs(3)) if (CheckArgs(3))
{ {
if (!(PClass=T_GetMobjType(t_argv[0]))) return; if (!(pclass=T_GetMobjType(t_argv[0]))) return;
x = fixedvalue(t_argv[1]); x = fixedvalue(t_argv[1]);
y = fixedvalue(t_argv[2]); y = fixedvalue(t_argv[2]);
@ -3356,7 +3356,7 @@ void FParser::SF_SpawnExplosion()
else else
z = P_PointInSector(x, y)->floorplane.ZatPoint(x,y); 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.type = svt_int;
t_return.value.i=0; t_return.value.i=0;
if (spawn) if (spawn)
@ -3514,15 +3514,15 @@ void FParser::SF_SpawnMissile()
{ {
AActor *mobj; AActor *mobj;
AActor *target; AActor *target;
const PClass * PClass; PClassActor * pclass;
if (CheckArgs(3)) if (CheckArgs(3))
{ {
if (!(PClass=T_GetMobjType(t_argv[2]))) return; if (!(pclass=T_GetMobjType(t_argv[2]))) return;
mobj = actorvalue(t_argv[0]); mobj = actorvalue(t_argv[0]);
target = actorvalue(t_argv[1]); 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) void FParser::SF_ThingCount(void)
{ {
const PClass *pClass; PClassActor *pClass;
AActor * mo; AActor * mo;
int count=0; int count=0;
bool replacemented = false; bool replacemented = false;
@ -4161,7 +4161,7 @@ void FParser::SF_ThingCount(void)
pClass=T_GetMobjType(t_argv[0]); pClass=T_GetMobjType(t_argv[0]);
if (!pClass) return; if (!pClass) return;
// If we want to count map items we must consider actor replacement // If we want to count map items we must consider actor replacement
pClass = pClass->ActorInfo->GetReplacement()->Class; pClass = pClass->GetReplacement();
again: again:
TThinkerIterator<AActor> it; TThinkerIterator<AActor> it;
@ -4191,7 +4191,7 @@ again:
{ {
// Again, with decorate replacements // Again, with decorate replacements
replacemented = true; replacemented = true;
PClass *newkind = pClass->ActorInfo->GetReplacement()->Class; PClassActor *newkind = pClass->GetReplacement();
if (newkind != pClass) if (newkind != pClass)
{ {
pClass = newkind; pClass = newkind;
@ -4259,7 +4259,7 @@ void FParser::SF_SetColor(void)
void FParser::SF_SpawnShot2(void) void FParser::SF_SpawnShot2(void)
{ {
AActor *source = NULL; AActor *source = NULL;
const PClass * PClass; PClassActor * pclass;
int z=0; int z=0;
// t_argv[0] = type to spawn // t_argv[0] = type to spawn
@ -4277,11 +4277,11 @@ void FParser::SF_SpawnShot2(void)
if(!source) return; if(!source) return;
if (!(PClass=T_GetMobjType(t_argv[0]))) return; if (!(pclass=T_GetMobjType(t_argv[0]))) return;
t_return.type = svt_mobj; 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) if (mo)
{ {
S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM); 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++) 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; DFsScript * gscr = global_script;

View file

@ -666,27 +666,12 @@ static int LS_FS_Execute (line_t *ln, AActor *it, bool backSide,
void FS_Close() void FS_Close()
{ {
int i; if (global_script != NULL)
DFsVariable *current, *next; {
GC::DelSoftRoot(global_script);
// we have to actually delete the global variables if we don't want global_script->Destroy();
// to get them reported as memory leaks. global_script = NULL;
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;
} }
void T_Init() void T_Init()
@ -700,7 +685,6 @@ void T_Init()
global_script = new DFsScript; global_script = new DFsScript;
GC::AddSoftRoot(global_script); GC::AddSoftRoot(global_script);
init_functions(); init_functions();
atterm(FS_Close);
} }
} }

View file

@ -8,18 +8,23 @@
*/ */
DEFINE_ACTION_FUNCTION(AActor, A_BspiAttack) DEFINE_ACTION_FUNCTION(AActor, A_BspiAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
// launch a missile // 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) DEFINE_ACTION_FUNCTION(AActor, A_BabyMetal)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "baby/walk", 1, ATTN_IDLE); 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) DEFINE_ACTION_FUNCTION(AActor, A_VileStart)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_VOICE, "vile/start", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_StartFire)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "vile/firestrt", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "vile/firestrt", 1, ATTN_NORM);
A_Fire (self, 0); A_Fire (self, 0);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle) DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "vile/firecrkl", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "vile/firecrkl", 1, ATTN_NORM);
A_Fire (self, 0); A_Fire (self, 0);
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_FIXED(height,0); PARAM_FIXED_OPT(height) { height = 0; }
A_Fire(self, height); A_Fire(self, height);
return 0;
} }
void A_Fire(AActor *self, int height) 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_CLASS(fire,0); PARAM_CLASS_OPT(fire, AActor) { fire = PClass::FindActor("ArchvileFire"); }
AActor *fog; AActor *fog;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
@ -88,6 +96,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
fog->target = self; fog->target = self;
fog->tracer = self->target; fog->tracer = self->target;
A_Fire(fog, 0); A_Fire(fog, 0);
return 0;
} }
@ -101,25 +110,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
#define VAF_DMGTYPEAPPLYTODIRECT 1 #define VAF_DMGTYPEAPPLYTODIRECT 1
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
{ {
ACTION_PARAM_START(7); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_SOUND(snd,0); PARAM_SOUND_OPT (snd) { snd = "vile/stop"; }
ACTION_PARAM_INT(dmg,1); PARAM_INT_OPT (dmg) { dmg = 20; }
ACTION_PARAM_INT(blastdmg,2); PARAM_INT_OPT (blastdmg) { blastdmg = 70; }
ACTION_PARAM_INT(blastrad,3); PARAM_INT_OPT (blastrad) { blastrad = 70; }
ACTION_PARAM_FIXED(thrust,4); PARAM_FIXED_OPT (thrust) { thrust = FRACUNIT; }
ACTION_PARAM_NAME(dmgtype,5); PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; }
ACTION_PARAM_INT(flags,6); PARAM_INT_OPT (flags) { flags = 0; }
AActor *fire, *target; AActor *fire, *target;
if (NULL == (target = self->target)) if (NULL == (target = self->target))
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
if (!P_CheckSight (self, target, 0) ) if (!P_CheckSight (self, target, 0) )
return; return 0;
S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM); 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); P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
} }
if (!(target->flags7 & MF7_DONTTHRUST)) if (!(target->flags7 & MF7_DONTTHRUST))
{
target->velz = Scale(thrust, 1000, target->Mass); 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) DEFINE_ACTION_FUNCTION(AActor, A_BrainAwake)
{ {
PARAM_ACTION_PROLOGUE;
// killough 3/26/98: only generates sound now // killough 3/26/98: only generates sound now
S_Sound (self, CHAN_VOICE, "brain/sight", 1, ATTN_NONE); S_Sound (self, CHAN_VOICE, "brain/sight", 1, ATTN_NONE);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BrainPain) DEFINE_ACTION_FUNCTION(AActor, A_BrainPain)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_VOICE, "brain/pain", 1, ATTN_NONE); S_Sound (self, CHAN_VOICE, "brain/pain", 1, ATTN_NONE);
return 0;
} }
static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) 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->DeathSound = "misc/brainexplode";
boom->velz = pr_brainscream() << 9; boom->velz = pr_brainscream() << 9;
const PClass *cls = PClass::FindClass("BossBrain"); PClassActor *cls = PClass::FindActor("BossBrain");
if (cls != NULL) if (cls != NULL)
{ {
FState *state = cls->ActorInfo->FindState(NAME_Brainexplode); FState *state = cls->FindState(NAME_Brainexplode);
if (state != NULL) if (state != NULL)
boom->SetState (state); boom->SetState (state);
} }
boom->effects = 0; 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; boom->tics -= pr_brainscream() & 7;
if (boom->tics < 1) if (boom->tics < 1)
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) DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t x; fixed_t x;
for (x = self->X() - 196*FRACUNIT; x < self->X() + 320*FRACUNIT; x += 8*FRACUNIT) 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))); 128 + (pr_brainscream() << (FRACBITS + 1)));
} }
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE); S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode) DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t x = self->X() + pr_brainexplode.Random2()*2048; fixed_t x = self->X() + pr_brainexplode.Random2()*2048;
fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT; fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT;
BrainishExplosion (x, self->Y(), z); BrainishExplosion (x, self->Y(), z);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BrainDie) DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
{ {
PARAM_ACTION_PROLOGUE;
// [RH] If noexit, then don't end the level. // [RH] If noexit, then don't end the level.
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT)) if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
return; return 0;
// New dmflag: Kill all boss spawned monsters before ending the level. // New dmflag: Kill all boss spawned monsters before ending the level.
if (dmflags2 & DF2_KILLBOSSMONST) if (dmflags2 & DF2_KILLBOSSMONST)
@ -98,18 +107,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
} }
G_ExitLevel (0, false); G_ExitLevel (0, false);
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
DSpotState *state = DSpotState::GetSpotState(); DSpotState *state = DSpotState::GetSpotState();
AActor *targ; AActor *targ;
AActor *spit; AActor *spit;
bool isdefault = false; bool isdefault = false;
ACTION_PARAM_START(1);
ACTION_PARAM_CLASS(spawntype, 0);
// shoot a cube at current target // shoot a cube at current target
targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain)); targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));
@ -117,7 +127,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{ {
if (spawntype == NULL) if (spawntype == NULL)
{ {
spawntype = PClass::FindClass("SpawnShot"); spawntype = PClass::FindActor("SpawnShot");
isdefault = true; isdefault = true;
} }
@ -161,9 +171,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE); 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 *newmobj;
AActor *fog; AActor *fog;
@ -191,8 +202,8 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
FName SpawnName; FName SpawnName;
FDropItem *di; // di will be our drop item list iterator DDropItem *di; // di will be our drop item list iterator
FDropItem *drop; // while drop stays as the reference point. DDropItem *drop; // while drop stays as the reference point.
int n = 0; int n = 0;
// First see if this cube has its own actor list // 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->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; di = drop;
@ -221,7 +232,7 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
{ {
if (di->Name != NAME_None) 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)) 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 if (r < 246) SpawnName = "HellKnight";
else SpawnName = "BaronOfHell"; else SpawnName = "BaronOfHell";
} }
spawntype = PClass::FindClass(SpawnName); spawntype = PClass::FindActor(SpawnName);
if (spawntype != NULL) if (spawntype != NULL)
{ {
newmobj = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE); 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
{ {
FSoundID sound; PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
ACTION_PARAM_START(1); FSoundID sound;
ACTION_PARAM_CLASS(spawntype, 0);
if (spawntype != NULL) if (spawntype != NULL)
{ {
@ -298,15 +309,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
} }
else else
{ {
spawntype = PClass::FindClass ("SpawnFire"); spawntype = PClass::FindActor("SpawnFire");
sound = "brain/spawn"; sound = "brain/spawn";
} }
SpawnFly(self, spawntype, sound); SpawnFly(self, spawntype, sound);
return 0;
} }
// travelling cube sound // travelling cube sound
DEFINE_ACTION_FUNCTION(AActor, A_SpawnSound) DEFINE_ACTION_FUNCTION(AActor, A_SpawnSound)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "brain/cube", 1, ATTN_IDLE); 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) DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
{ {
@ -12,9 +14,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
S_Sound (self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
// launch a missile // 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) DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -24,9 +26,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
// launch a missile // 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) DEFINE_ACTION_FUNCTION(AActor, A_CyberAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); 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) DEFINE_ACTION_FUNCTION(AActor, A_Hoof)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "cyber/hoof", 1, ATTN_IDLE); 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) DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -23,4 +25,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
} }
return 0;
} }

View file

@ -28,7 +28,7 @@ public:
void BeginPlay (); void BeginPlay ();
void Tick (); void Tick ();
void SetWeapon (EMarineWeapon); void SetWeapon (EMarineWeapon);
void SetSprite (const PClass *source); void SetSprite (PClassActor *source);
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
int CurrentWeapon; int CurrentWeapon;

View file

@ -17,8 +17,10 @@ static FRandom pr_troopattack ("TroopAttack");
// //
DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack) DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -27,9 +29,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
S_Sound (self, CHAN_WEAPON, "imp/melee", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "imp/melee", 1, ATTN_NORM);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
// launch a missile // 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) DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
{ {
PARAM_ACTION_PROLOGUE;
if (dmflags2 & DF2_BARRELS_RESPAWN) if (dmflags2 & DF2_BARRELS_RESPAWN)
{ {
self->height = self->GetDefault()->height; self->height = self->GetDefault()->height;
@ -48,4 +50,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
{ {
self->Destroy (); self->Destroy ();
} }
return 0;
} }

View file

@ -28,6 +28,8 @@ static FRandom pr_oldbfg ("OldBFG");
// //
DEFINE_ACTION_FUNCTION(AActor, A_Punch) DEFINE_ACTION_FUNCTION(AActor, A_Punch)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int pitch; 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 != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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); S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
self->angle = self->AngleTo(linetarget); self->angle = self->AngleTo(linetarget);
} }
return 0;
} }
// //
@ -68,6 +71,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
// //
DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
{ {
PARAM_ACTION_PROLOGUE;
bool accurate; bool accurate;
if (self->player != NULL) if (self->player != NULL)
@ -76,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return; return 0;
P_SetPsprite (self->player, ps_flash, weapon->FindState(NAME_Flash)); 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); 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) 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 angle;
angle_t slope; angle_t slope;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
int actualdamage; 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)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff); if (pufftype == NULL)
if (damage == 0) damage = 2; {
pufftype = PClass::FindActor(NAME_BulletPuff);
if (!(Flags & SF_NORANDOM)) }
if (damage == 0)
{
damage = 2;
}
if (!(flags & SF_NORANDOM))
{
damage *= (pr_saw()%10+1); damage *= (pr_saw()%10+1);
}
// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) if (range == 0)
if (Range == 0) Range = MELEERANGE+1; { // 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)); angle = self->angle + (pr_saw.Random2() * (spread_xy / 255));
slope = P_AimLineAttack (self, angle, Range, &linetarget) + (pr_saw.Random2() * (Spread_Z / 255)); slope = P_AimLineAttack (self, angle, range, &linetarget) + (pr_saw.Random2() * (spread_z / 255));
AWeapon *weapon = self->player->ReadyWeapon; 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)) 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 (!linetarget)
{ {
if ((Flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64)) if ((flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64))
{ {
player->extralight = !player->extralight; player->extralight = !player->extralight;
} }
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
return; return 0;
} }
if (Flags & SF_RANDOMLIGHTHIT) if (flags & SF_RANDOMLIGHTHIT)
{ {
int randVal = pr_saw(); int randVal = pr_saw();
if (randVal < 64) 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 == NULL)
if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
{ {
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE)); armorbonustype = dyn_cast<ABasicArmorBonus::MetaClass>(PClass::FindClass("ArmorBonus"));
armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS; }
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->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
armorbonus->flags |= MF_DROPPED; armorbonus->flags |= MF_DROPPED;
armorbonus->ClearCounters(); armorbonus->ClearCounters();
@ -206,14 +223,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
else else
{ {
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS, lifestealmax); P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax);
} }
} }
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
// turn to face target // turn to face target
if (!(Flags & SF_NOTURN)) if (!(flags & SF_NOTURN))
{ {
angle = self->AngleTo(linetarget); angle = self->AngleTo(linetarget);
if (angle - self->angle > ANG180) if (angle - self->angle > ANG180)
@ -231,8 +248,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
self->angle += ANG90 / 20; self->angle += ANG90 / 20;
} }
} }
if (!(Flags & SF_NOPULLIN)) if (!(flags & SF_NOPULLIN))
self->flags |= MF_JUSTATTACKED; self->flags |= MF_JUSTATTACKED;
return 0;
} }
// //
@ -240,12 +258,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
// //
DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM); 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 != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return; return 0;
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash)); P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
} }
player->mo->PlayAttacking2 (); player->mo->PlayAttacking2 ();
angle_t pitch = P_BulletSlope (self); angle_t pitch = P_BulletSlope (self);
for (i=0 ; i<7 ; i++) for (i = 0; i < 7; i++)
P_GunShot (self, false, PClass::FindClass(NAME_BulletPuff), pitch); {
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) DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
angle_t angle; angle_t angle;
int damage; int damage;
@ -276,7 +301,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM); 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 != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2))
return; return 0;
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash)); P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
} }
player->mo->PlayAttacking2 (); player->mo->PlayAttacking2 ();
@ -310,22 +335,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
pitch + (pr_fireshotgun2.Random2() * 332063), damage, pitch + (pr_fireshotgun2.Random2() * 332063), damage,
NAME_Hitscan, NAME_BulletPuff); NAME_Hitscan, NAME_BulletPuff);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_OpenShotgun2) DEFINE_ACTION_FUNCTION(AActor, A_OpenShotgun2)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_LoadShotgun2) DEFINE_ACTION_FUNCTION(AActor, A_LoadShotgun2)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2) DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);
A_ReFire (self); 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) 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)) while (cls != RUNTIME_CLASS(AWeapon))
{ {
FActorInfo * info = cls->ActorInfo; if (flashstate >= cls->OwnedStates && flashstate < cls->OwnedStates + cls->NumOwnedStates)
if (flashstate >= info->OwnedStates && flashstate < info->OwnedStates + info->NumOwnedStates)
{ {
// The flash state belongs to this class. // The flash state belongs to this class.
// Now let's check if the actually wanted state does also // 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 // we're ok so set the state
P_SetPsprite (player, ps_flash, flashstate + index); 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 // 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 // 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. // 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) DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (self == NULL || NULL == (player = self->player)) if (self == NULL || NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return; return 0;
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
@ -416,7 +449,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
} }
player->mo->PlayAttacking2 (); 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) DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(grenade, AActor) { grenade = PClass::FindActor("Grenade"); }
player_t *player; player_t *player;
ACTION_PARAM_START(1);
ACTION_PARAM_CLASS(grenade, 0); if (grenade == NULL)
if (grenade == NULL) return; return 0;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
// Temporarily raise the pitch to send the grenade slightly upwards // 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); self->pitch -= (1152 << FRACBITS);
P_SpawnPlayerMissile(self, grenade); P_SpawnPlayerMissile(self, grenade);
self->pitch = SavedPlayerPitch; self->pitch = SavedPlayerPitch;
return 0;
} }
// //
@ -472,17 +513,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
// //
DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma) DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return; return 0;
FState *flash = weapon->FindState(NAME_Flash); FState *flash = weapon->FindState(NAME_Flash);
if (flash != NULL) 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) DEFINE_ACTION_FUNCTION(AActor, A_FireRailgun)
{ {
PARAM_ACTION_PROLOGUE;
FireRailgun(self, 0, ACTION_CALL_FROM_WEAPON()); FireRailgun(self, 0, ACTION_CALL_FROM_WEAPON());
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunRight) DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunRight)
{ {
PARAM_ACTION_PROLOGUE;
FireRailgun(self, 10, ACTION_CALL_FROM_WEAPON()); FireRailgun(self, 10, ACTION_CALL_FROM_WEAPON());
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunLeft) DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunLeft)
{ {
PARAM_ACTION_PROLOGUE;
FireRailgun(self, -10, ACTION_CALL_FROM_WEAPON()); FireRailgun(self, -10, ACTION_CALL_FROM_WEAPON());
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_RailWait) DEFINE_ACTION_FUNCTION(AActor, A_RailWait)
{ {
// Okay, this was stupid. Just use a NULL function instead of this. // 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) DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, deh.BFGCells)) 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) 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 i;
int j; int j;
int damage; int damage;
angle_t an; angle_t an;
AActor *linetarget; AActor *linetarget;
ACTION_PARAM_START(7); if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
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 (numrays <= 0) numrays = 40; if (numrays <= 0) numrays = 40;
if (damagecnt <= 0) damagecnt = 15; if (damagecnt <= 0) damagecnt = 15;
if (angle == 0) angle = ANG90; if (angle == 0) angle = ANG90;
@ -600,7 +654,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
// [RH] Don't crash if no target // [RH] Don't crash if no target
if (!self->target) if (!self->target)
return; return 0;
// offset angles from its attack angle // offset angles from its attack angle
for (i = 0; i < numrays; i++) 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM); 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) 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; AActor * mo = NULL;
player_t *player; player_t *player;
@ -675,7 +733,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
@ -683,7 +741,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return; return 0;
doesautoaim = !(weapon->WeaponFlags & WIF_NOAUTOAIM); doesautoaim = !(weapon->WeaponFlags & WIF_NOAUTOAIM);
weapon->WeaponFlags |= WIF_NOAUTOAIM; // No autoaiming that gun weapon->WeaponFlags |= WIF_NOAUTOAIM; // No autoaiming that gun
@ -702,5 +760,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
self->angle = SavedPlayerAngle; self->angle = SavedPlayerAngle;
self->pitch = SavedPlayerPitch; 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) DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
{ {
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self); A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile; AActor *missile;
angle_t an; angle_t an;
if (!self->target) if (!self->target)
return; return 0;
ACTION_PARAM_START(1); if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
ACTION_PARAM_CLASS(spawntype, 0);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self); A_FaceTarget (self);
// Change direction to ... // Change direction to ...
@ -49,20 +52,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->velx = FixedMul (missile->Speed, finecosine[an]);
missile->vely = FixedMul (missile->Speed, finesine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile; AActor *missile;
angle_t an; angle_t an;
if (!self->target) if (!self->target)
return; return 0;
ACTION_PARAM_START(1); if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
ACTION_PARAM_CLASS(spawntype, 0);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self); A_FaceTarget (self);
// Now here choose opposite deviation. // Now here choose opposite deviation.
@ -77,20 +81,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->velx = FixedMul (missile->Speed, finecosine[an]);
missile->vely = FixedMul (missile->Speed, finesine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile; AActor *missile;
angle_t an; angle_t an;
if (!self->target) if (!self->target)
return; return 0;
ACTION_PARAM_START(1); if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
ACTION_PARAM_CLASS(spawntype, 0);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self); A_FaceTarget (self);
@ -111,6 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->velx = FixedMul (missile->Speed, finecosine[an]);
missile->vely = FixedMul (missile->Speed, finesine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]);
} }
return 0;
} }
// //
@ -118,8 +124,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
// Original idea: Linguica // Original idea: Linguica
// //
AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const PClass *type);
enum enum
{ {
MSF_Standard = 0, MSF_Standard = 0,
@ -129,17 +133,23 @@ enum
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) 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; int i, j;
ACTION_PARAM_START(5); if (n == 0)
ACTION_PARAM_CLASS(spawntype, 0); {
ACTION_PARAM_INT(n, 1); n = self->GetMissileDamage(0, 1);
ACTION_PARAM_INT(flags, 2); }
ACTION_PARAM_FIXED(vrange, 3); if (spawntype == NULL)
ACTION_PARAM_FIXED(hrange, 4); {
spawntype = PClass::FindActor("FatShot");
if (n == 0) n = self->Damage; // GetMissileDamage (0, 1); }
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE); P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE);
P_CheckSplash(self, 128<<FRACBITS); P_CheckSplash(self, 128<<FRACBITS);
@ -176,4 +186,5 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
} }
} }
target->Destroy(); target->Destroy();
return 0;
} }

View file

@ -13,8 +13,12 @@
// DOOM II special, map 32. // DOOM II special, map 32.
// Uses special tag 666 by default. // Uses special tag 666 by default.
// //
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie)
{ {
PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT(doortag) { doortag = 666; }
A_Unblock(self, false); A_Unblock(self, false);
// scan the remaining thinkers to see if all Keens are dead // 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)) if (other != self && other->health > 0 && other->IsA (matchClass))
{ {
// other Keen not dead // 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); 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_FIXED(n, 0); PARAM_FIXED_OPT(speed) { speed = SKULLSPEED; }
if (n <= 0) n = SKULLSPEED; if (speed <= 0)
A_SkullAttack(self, n); speed = SKULLSPEED;
A_SkullAttack(self, speed);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack) DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack)
{ {
PARAM_ACTION_PROLOGUE;
int damage; int damage;
if (!self || !self->target || self->target->GetSpecies() == self->GetSpecies()) if (!self || !self->target || self->target->GetSpecies() == self->GetSpecies())
return; return 0;
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget(self); 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); P_DamageMobj(self->target, self, self, damage, NAME_None);
return 0;
} }

View file

@ -12,13 +12,22 @@
DECLARE_ACTION(A_SkullAttack) DECLARE_ACTION(A_SkullAttack)
static const PClass *GetSpawnType(DECLARE_PARAMINFO) static PClassActor *GetSpawnType(VMValue *param)
{ {
ACTION_PARAM_START(1); PClassActor *spawntype;
ACTION_PARAM_CLASS(spawntype, 0);
if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul"); if (param == NULL || param->Type == REGT_NIL)
return spawntype; {
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 // A_PainShootSkull
// Spawn a lost soul and launch it at the target // 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; AActor *other;
int prestep; int prestep;
if (spawntype == NULL) return; 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 // [RH] check to make sure it's not too close to the ceiling
if (self->Top() + 8*FRACUNIT > self->ceilingz) 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
ACTION_PARAM_START(4); PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
ACTION_PARAM_CLASS(spawntype, 0); PARAM_ANGLE_OPT (angle) { angle = 0; }
ACTION_PARAM_ANGLE(angle, 1); PARAM_INT_OPT (flags) { flags = 0; }
ACTION_PARAM_INT(flags, 2); PARAM_INT_OPT (limit) { limit = -1; }
ACTION_PARAM_INT(limit, 3);
if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul"); if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
if (!(flags & PAF_AIMFACING)) if (!(flags & PAF_AIMFACING))
A_FaceTarget (self); A_FaceTarget (self);
A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit); A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit);
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
{ {
if (!self->target) PARAM_ACTION_PROLOGUE;
return;
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO); if (!self->target)
return 0;
PClassActor *spawntype = GetSpawnType(numparam > NAP ? &param[NAP] : NULL);
A_FaceTarget (self); A_FaceTarget (self);
A_PainShootSkull (self, self->angle + ANG45, spawntype); A_PainShootSkull (self, self->angle + ANG45, spawntype);
A_PainShootSkull (self, self->angle - ANG45, spawntype); A_PainShootSkull (self, self->angle - ANG45, spawntype);
return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie) 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! { // And I thought you were my friend!
self->flags &= ~MF_FRIENDLY; self->flags &= ~MF_FRIENDLY;
} }
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO); PClassActor *spawntype = GetSpawnType(numparam > NAP ? &param[NAP] : NULL);
A_Unblock(self, true); A_Unblock(self, true);
A_PainShootSkull (self, self->angle + ANG90, spawntype); A_PainShootSkull (self, self->angle + ANG90, spawntype);
A_PainShootSkull (self, self->angle + ANG180, spawntype); A_PainShootSkull (self, self->angle + ANG180, spawntype);
A_PainShootSkull (self, self->angle + ANG270, 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) DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
{ {
PARAM_ACTION_PROLOGUE;
int angle; int angle;
int damage; int damage;
int slope; int slope;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
angle = self->angle; angle = self->angle;
@ -35,6 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
angle += pr_posattack.Random2() << 20; angle += pr_posattack.Random2() << 20;
damage = ((pr_posattack()%5)+1)*3; damage = ((pr_posattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;
} }
static void A_SPosAttack2 (AActor *self) static void A_SPosAttack2 (AActor *self)
@ -57,33 +60,41 @@ static void A_SPosAttack2 (AActor *self)
DEFINE_ACTION_FUNCTION(AActor, A_SPosAttackUseAtkSound) DEFINE_ACTION_FUNCTION(AActor, A_SPosAttackUseAtkSound)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_SPosAttack2 (self); A_SPosAttack2 (self);
return 0;
} }
// This version of the function, which uses a hard-coded sound, is // This version of the function, which uses a hard-coded sound, is
// meant for Dehacked only. // meant for Dehacked only.
DEFINE_ACTION_FUNCTION(AActor, A_SPosAttack) DEFINE_ACTION_FUNCTION(AActor, A_SPosAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
S_Sound (self, CHAN_WEAPON, "shotguy/attack", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "shotguy/attack", 1, ATTN_NORM);
A_SPosAttack2 (self); A_SPosAttack2 (self);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
{ {
PARAM_ACTION_PROLOGUE;
int angle; int angle;
int bangle; int bangle;
int damage; int damage;
int slope; int slope;
if (!self->target) if (!self->target)
return; return 0;
// [RH] Andy Baker's stealth monsters // [RH] Andy Baker's stealth monsters
if (self->flags & MF_STEALTH) if (self->flags & MF_STEALTH)
@ -99,15 +110,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
angle = bangle + (pr_cposattack.Random2() << 20); angle = bangle + (pr_cposattack.Random2() << 20);
damage = ((pr_cposattack()%5)+1)*3; damage = ((pr_cposattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire) DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire)
{ {
PARAM_ACTION_PROLOGUE;
// keep firing unless target got out of sight // keep firing unless target got out of sight
A_FaceTarget (self); A_FaceTarget (self);
if (pr_cposrefire() < 40) if (pr_cposrefire() < 40)
return; return 0;
if (!self->target if (!self->target
|| P_HitFriend (self) || P_HitFriend (self)
@ -116,4 +130,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire)
{ {
self->SetState (self->SeeState); self->SetState (self->SeeState);
} }
return 0;
} }

View file

@ -19,27 +19,32 @@ static FRandom pr_skelfist ("SkelFist");
// A_SkelMissile // A_SkelMissile
// //
DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile) DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile)
{ {
PARAM_ACTION_PROLOGUE;
AActor *missile; AActor *missile;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
missile = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, missile = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT,
self->target, PClass::FindClass("RevenantTracer")); self->target, PClass::FindActor("RevenantTracer"));
if (missile != NULL) if (missile != NULL)
{ {
missile->SetOrigin(missile->Vec3Offset(missile->velx, missile->vely, 0), false); missile->SetOrigin(missile->Vec3Offset(missile->velx, missile->vely, 0), false);
missile->tracer = self->target; missile->tracer = self->target;
} }
return 0;
} }
#define TRACEANGLE (0xc000000) #define TRACEANGLE (0xc000000)
DEFINE_ACTION_FUNCTION(AActor, A_Tracer) DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
{ {
PARAM_ACTION_PROLOGUE;
angle_t exact; angle_t exact;
fixed_t dist; fixed_t dist;
fixed_t slope; 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. // [RH] level.time is always 0-based, so nothing special to do here.
if (level.time & 3) if (level.time & 3)
return; return 0;
// spawn a puff of smoke behind the rocket // 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); 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; dest = self->tracer;
if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest)) if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest))
return; return 0;
// change angle // change angle
exact = self->AngleTo(dest); exact = self->AngleTo(dest);
@ -119,21 +124,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
else else
self->velz += FRACUNIT/8; self->velz += FRACUNIT/8;
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_SkelWhoosh) DEFINE_ACTION_FUNCTION(AActor, A_SkelWhoosh)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "skeleton/swing", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "skeleton/swing", 1, ATTN_NORM);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_SkelFist) DEFINE_ACTION_FUNCTION(AActor, A_SkelFist)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
@ -144,4 +155,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelFist)
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_BOOL(ignoremissile, 0); PARAM_BOOL_OPT(ignoremissile) { ignoremissile = false; }
if (self->target == NULL || self->target->health <= 0) 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 { // Look for a new target most of the time
if (P_LookForPlayers (self, true, NULL) && P_CheckMissileRange (self)) if (P_LookForPlayers (self, true, NULL) && P_CheckMissileRange (self))
{ // Found somebody new and in range, so don't stop shooting { // Found somebody new and in range, so don't stop shooting
return; return 0;
} }
} }
self->SetState (self->state + 1); self->SetState (self->state + 1);
return; return 0;
} }
if (((ignoremissile || self->MissileState == NULL) && !self->CheckMeleeRange ()) || if (((ignoremissile || self->MissileState == NULL) && !self->CheckMeleeRange ()) ||
!P_CheckSight (self, self->target) || !P_CheckSight (self, self->target) ||
@ -176,6 +176,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Refire)
{ {
self->SetState (self->state + 1); 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) DEFINE_ACTION_FUNCTION(AActor, A_M_SawRefire)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL || self->target->health <= 0) if (self->target == NULL || self->target->health <= 0)
{ {
self->SetState (self->state + 1); self->SetState (self->state + 1);
return; return 0;
} }
if (!self->CheckMeleeRange ()) if (!self->CheckMeleeRange ())
{ {
self->SetState (self->state + 1); self->SetState (self->state + 1);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -205,10 +209,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_SawRefire)
DEFINE_ACTION_FUNCTION(AActor, A_MarineNoise) DEFINE_ACTION_FUNCTION(AActor, A_MarineNoise)
{ {
PARAM_ACTION_PROLOGUE;
if (static_cast<AScriptedMarine *>(self)->CurrentWeapon == AScriptedMarine::WEAPON_Chainsaw) if (static_cast<AScriptedMarine *>(self)->CurrentWeapon == AScriptedMarine::WEAPON_Chainsaw)
{ {
S_Sound (self, CHAN_WEAPON, "weapons/sawidle", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_MarineChase)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_MarineNoise, self); 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) DEFINE_ACTION_FUNCTION(AActor, A_MarineLook)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_MarineNoise, self); CALL_ACTION(A_MarineNoise, self);
CALL_ACTION(A_Look, 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
{ {
ACTION_PARAM_START(4); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_SOUND(fullsound, 0); PARAM_SOUND_OPT (fullsound) { fullsound = "weapons/sawfull"; }
ACTION_PARAM_SOUND(hitsound, 1); PARAM_SOUND_OPT (hitsound) { hitsound = "weapons/sawhit"; }
ACTION_PARAM_INT(damage, 2); PARAM_INT_OPT (damage) { damage = 2; }
ACTION_PARAM_CLASS(pufftype, 3); PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; }
if (self->target == NULL) if (self->target == NULL)
return; return 0;
if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff); if (pufftype == NULL)
if (damage == 0) damage = 2; {
pufftype = PClass::FindActor(NAME_BulletPuff);
}
if (damage == 0)
{
damage = 2;
}
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -271,7 +288,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
if (!linetarget) if (!linetarget)
{ {
S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM); 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); S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
} }
//A_Chase (self); //A_Chase (self);
return 0;
} }
//============================================================================ //============================================================================
@ -333,10 +351,11 @@ static void MarinePunch(AActor *self, int damagemul)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_INT(mult, 0); PARAM_INT(mult);
MarinePunch(self, 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; angle_t angle;
int damage; 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
{ {
if (self->target == NULL) PARAM_ACTION_PROLOGUE;
return; PARAM_BOOL(accurate);
ACTION_PARAM_START(1); if (self->target == NULL)
ACTION_PARAM_BOOL(accurate, 0); return 0;
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
A_FaceTarget (self); A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), 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) DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
{ {
PARAM_ACTION_PROLOGUE;
int pitch; int pitch;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
A_FaceTarget (self); A_FaceTarget (self);
pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
for (int i = 0; i < 7; ++i) 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; 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) DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (self->special1 != 0 || self->target == NULL) if (self->special1 != 0 || self->target == NULL)
{ {
self->SetState (self->FindState("SkipAttack")); self->SetState (self->FindState("SkipAttack"));
@ -420,6 +445,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
{ {
A_FaceTarget (self); A_FaceTarget (self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -430,10 +456,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_CheckAttack)
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2) DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
{ {
PARAM_ACTION_PROLOGUE;
int pitch; int pitch;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
A_FaceTarget (self); A_FaceTarget (self);
@ -448,6 +476,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
NAME_Hitscan, NAME_BulletPuff); NAME_Hitscan, NAME_BulletPuff);
} }
self->special1 = level.maptime; 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
{ {
if (self->target == NULL) PARAM_ACTION_PROLOGUE;
return; PARAM_BOOL(accurate);
ACTION_PARAM_START(1); if (self->target == NULL)
ACTION_PARAM_BOOL(accurate, 0); return 0;
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
A_FaceTarget (self); A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), 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) DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
{ // If too close, punch it { // If too close, punch it
@ -492,8 +524,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile)
else else
{ {
A_FaceTarget (self); 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) DEFINE_ACTION_FUNCTION(AActor, A_M_FireRailgun)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
CALL_ACTION(A_MonsterRail, self); CALL_ACTION(A_MonsterRail, self);
self->special1 = level.maptime + 50; 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) DEFINE_ACTION_FUNCTION(AActor, A_M_FirePlasma)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
A_FaceTarget (self); A_FaceTarget (self);
P_SpawnMissile (self, self->target, PClass::FindClass("PlasmaBall")); P_SpawnMissile (self, self->target, PClass::FindActor("PlasmaBall"));
self->special1 = level.maptime + 20; 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) DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
if (self->special1 != 0) if (self->special1 != 0)
{ {
@ -549,6 +590,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
// Don't interrupt the firing sequence // Don't interrupt the firing sequence
self->PainChance = 0; self->PainChance = 0;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -559,13 +601,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
DEFINE_ACTION_FUNCTION(AActor, A_M_FireBFG) DEFINE_ACTION_FUNCTION(AActor, A_M_FireBFG)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
A_FaceTarget (self); 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->special1 = level.maptime + 30;
self->PainChance = MARINE_PAIN_CHANCE; 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 { // 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 // Copy the standard scaling
scaleX = GetDefault()->scaleX; scaleX = GetDefault()->scaleX;
scaleY = GetDefault()->scaleY; scaleY = GetDefault()->scaleY;

View file

@ -13,11 +13,13 @@ static FRandom pr_spidrefire ("SpidRefire");
DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire) DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire)
{ {
PARAM_ACTION_PROLOGUE;
// keep firing unless target got out of sight // keep firing unless target got out of sight
A_FaceTarget (self); A_FaceTarget (self);
if (pr_spidrefire() < 10) if (pr_spidrefire() < 10)
return; return 0;
if (!self->target if (!self->target
|| P_HitFriend (self) || P_HitFriend (self)
@ -26,10 +28,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire)
{ {
self->SetState (self->SeeState); self->SetState (self->SeeState);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_Metal) DEFINE_ACTION_FUNCTION(AActor, A_Metal)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "spider/walk", 1, ATTN_IDLE); S_Sound (self, CHAN_BODY, "spider/walk", 1, ATTN_IDLE);
A_Chase (self); A_Chase (stack, self);
return 0;
} }

View file

@ -258,10 +258,10 @@ void InitActorNumsFromMapinfo()
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
const PClass *cls = NULL; PClassActor *cls = NULL;
if (pair->Value.classname != NAME_None) if (pair->Value.classname != NAME_None)
{ {
cls = PClass::FindClass(pair->Value.classname); cls = PClass::FindActor(pair->Value.classname);
if (cls == NULL) if (cls == NULL)
{ {
Printf(TEXTCOLOR_RED "Script error, \"%s\" line %d:\nUnknown actor class %s\n", 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) if (argv.argc() > 1 && who != NULL)
{ {
SendItemUse = who->FindInventory (PClass::FindClass (argv[1])); SendItemUse = who->FindInventory(PClass::FindActor(argv[1]));
} }
} }
CCMD (invdrop) CCMD (invdrop)
{ {
if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel; if (players[consoleplayer].mo)
{
SendItemDrop = players[consoleplayer].mo->InvSel;
}
} }
CCMD (weapdrop) CCMD (weapdrop)
@ -457,11 +460,11 @@ CCMD (drop)
{ {
if (argv.argc() > 1 && who != NULL) 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) CCMD (useflechette)
{ // Select from one of arti_poisonbag1-3, whichever the player has { // Select from one of arti_poisonbag1-3, whichever the player has
@ -475,7 +478,7 @@ CCMD (useflechette)
if (who == NULL) if (who == NULL)
return; return;
const PClass *type = GetFlechetteType(who); PClassActor *type = GetFlechetteType(who);
if (type != NULL) if (type != NULL)
{ {
AInventory *item; AInventory *item;
@ -502,7 +505,7 @@ CCMD (select)
{ {
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
AInventory *item = who->FindInventory (PClass::FindClass (argv[1])); AInventory *item = who->FindInventory(PClass::FindActor(argv[1]));
if (item != NULL) if (item != NULL)
{ {
who->InvSel = item; who->InvSel = item;
@ -1350,7 +1353,7 @@ void G_PlayerReborn (int player)
BYTE currclass; BYTE currclass;
userinfo_t userinfo; // [RH] Save userinfo userinfo_t userinfo; // [RH] Save userinfo
APlayerPawn *actor; APlayerPawn *actor;
const PClass *cls; PClassPlayerPawn *cls;
FString log; FString log;
DBot *Bot; //Added by MC: DBot *Bot; //Added by MC:

View file

@ -66,9 +66,11 @@ void AChickenPlayer::MorphPlayerThink ()
DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack) DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
{ {
@ -76,6 +78,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); 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) DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
int count; int count;
AActor *mo; AActor *mo;
@ -107,6 +112,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
mo->velz = FRACUNIT + (pr_feathers() << 9); mo->velz = FRACUNIT + (pr_feathers() << 9);
mo->SetState (mo->SpawnState + (pr_feathers()&7)); mo->SetState (mo->SpawnState + (pr_feathers()&7));
} }
return 0;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -132,14 +138,17 @@ void P_UpdateBeak (AActor *self)
DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
player->psprites[ps_weapon].sy = WEAPONTOP; player->psprites[ps_weapon].sy = WEAPONTOP;
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); 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) DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
@ -169,7 +180,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
damage = 1 + (pr_beakatkpl1()&3); damage = 1 + (pr_beakatkpl1()&3);
@ -183,6 +194,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
P_PlayPeck (player->mo); P_PlayPeck (player->mo);
player->chickenPeck = 12; player->chickenPeck = 12;
player->psprites[ps_weapon].tics -= pr_beakatkpl1() & 7; 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) DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
@ -201,7 +215,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
damage = pr_beakatkpl2.HitDice (4); damage = pr_beakatkpl2.HitDice (4);
@ -215,4 +229,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
P_PlayPeck (player->mo); P_PlayPeck (player->mo);
player->chickenPeck = 12; player->chickenPeck = 12;
player->psprites[ps_weapon].tics -= pr_beakatkpl2()&3; 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) DEFINE_ACTION_FUNCTION(AActor, A_Sor1Pain)
{ {
PARAM_ACTION_PROLOGUE;
self->special1 = 20; // Number of steps to walk fast self->special1 = 20; // Number of steps to walk fast
CALL_ACTION(A_Pain, self); CALL_ACTION(A_Pain, self);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -40,12 +43,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_Sor1Pain)
DEFINE_ACTION_FUNCTION(AActor, A_Sor1Chase) DEFINE_ACTION_FUNCTION(AActor, A_Sor1Chase)
{ {
PARAM_ACTION_PROLOGUE;
if (self->special1) if (self->special1)
{ {
self->special1--; self->special1--;
self->tics -= 3; 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) DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
fixed_t velz; fixed_t velz;
angle_t angle; angle_t angle;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -72,10 +80,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
int damage = pr_scrc1atk.HitDice (8); int damage = pr_scrc1atk.HitDice (8);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); 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) if (self->health > (self->SpawnHealth()/3)*2)
{ // Spit one fireball { // Spit one fireball
P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx ); 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) DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
self->flags &= ~MF_SOLID; self->flags &= ~MF_SOLID;
@ -121,6 +132,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
mo->SetState (mo->FindState("Rise")); mo->SetState (mo->FindState("Rise"));
mo->angle = self->angle; mo->angle = self->angle;
mo->CopyFriendliness (self, true); mo->CopyFriendliness (self, true);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -167,6 +179,7 @@ void P_DSparilTeleport (AActor *actor)
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide) DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
{ {
PARAM_ACTION_PROLOGUE;
static const int chance[] = static const int chance[] =
{ {
@ -183,6 +196,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
{ {
P_DSparilTeleport (self); P_DSparilTeleport (self);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -193,11 +207,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Decide)
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
{ {
PARAM_ACTION_PROLOGUE;
int chance; int chance;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NONE); S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NONE);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -205,13 +221,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
int damage = pr_s2a.HitDice (20); int damage = pr_s2a.HitDice (20);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
chance = self->health < self->SpawnHealth()/2 ? 96 : 48; chance = self->health < self->SpawnHealth()/2 ? 96 : 48;
if (pr_s2a() < chance) if (pr_s2a() < chance)
{ // Wizard spawners { // Wizard spawners
const PClass *fx = PClass::FindClass("Sorcerer2FX2"); PClassActor *fx = PClass::FindActor("Sorcerer2FX2");
if (fx) if (fx)
{ {
P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2); P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2);
@ -220,8 +236,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
} }
else else
{ // Blue bolt { // 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) DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
AActor *mo; AActor *mo;
@ -242,6 +261,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
mo->vely = pr_bluespark.Random2() << 9; mo->vely = pr_bluespark.Random2() << 9;
mo->velz = FRACUNIT + (pr_bluespark()<<8); mo->velz = FRACUNIT + (pr_bluespark()<<8);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -252,6 +272,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE); mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
@ -275,6 +297,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
Spawn<ATeleportFog> (self->Pos(), ALLOW_REPLACE); Spawn<ATeleportFog> (self->Pos(), ALLOW_REPLACE);
} }
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -285,8 +308,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit) DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit)
{ {
PARAM_ACTION_PROLOGUE;
self->special1 = 7; // Animation loop counter self->special1 = 7; // Animation loop counter
P_Massacre (); // Kill monsters early P_Massacre (); // Kill monsters early
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -297,9 +323,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthInit)
DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthLoop) DEFINE_ACTION_FUNCTION(AActor, A_Sor2DthLoop)
{ {
PARAM_ACTION_PROLOGUE;
if (--self->special1) if (--self->special1)
{ // Need to loop { // Need to loop
self->SetState (self->FindState("DeathLoop")); self->SetState (self->FindState("DeathLoop"));
} }
return 0;
} }

View file

@ -47,12 +47,15 @@ bool AArtiTomeOfPower::Use (bool pickup)
DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb) DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
{ {
PARAM_ACTION_PROLOGUE;
self->AddZ(32*FRACUNIT, false); self->AddZ(32*FRACUNIT, false);
self->PrevZ = self->Z(); // no interpolation! self->PrevZ = self->Z(); // no interpolation!
self->RenderStyle = STYLE_Add; self->RenderStyle = STYLE_Add;
self->alpha = FRACUNIT; self->alpha = FRACUNIT;
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
P_CheckSplash(self, 128<<FRACBITS); P_CheckSplash(self, 128<<FRACBITS);
return 0;
} }
class AArtiTimeBomb : public AInventory class AArtiTimeBomb : public AInventory

View file

@ -21,12 +21,15 @@ static FRandom pr_imp ("ImpExplode");
DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack) DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target || pr_impmsatk() > 64) if (!self->target || pr_impmsatk() > 64)
{ {
self->SetState (self->SeeState); self->SetState (self->SeeState);
return; return 0;
} }
A_SkullAttack(self, 12 * FRACUNIT); A_SkullAttack(self, 12 * FRACUNIT);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -37,6 +40,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode) DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
{ {
PARAM_ACTION_PROLOGUE;
AActor *chunk; AActor *chunk;
self->flags &= ~MF_NOGRAVITY; self->flags &= ~MF_NOGRAVITY;
@ -54,6 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
{ // Extreme death crash { // Extreme death crash
self->SetState (self->FindState("XCrash")); self->SetState (self->FindState("XCrash"));
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -64,8 +70,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath) DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath)
{ {
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_SOLID; self->flags &= ~MF_SOLID;
self->flags2 |= MF2_FLOORCLIP; self->flags2 |= MF2_FLOORCLIP;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -76,9 +85,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpDeath)
DEFINE_ACTION_FUNCTION(AActor, A_ImpXDeath1) DEFINE_ACTION_FUNCTION(AActor, A_ImpXDeath1)
{ {
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_SOLID; self->flags &= ~MF_SOLID;
self->flags |= MF_NOGRAVITY; self->flags |= MF_NOGRAVITY;
self->flags2 |= MF2_FLOORCLIP; self->flags2 |= MF2_FLOORCLIP;
self->special1 = 666; // Flag the crash routine 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_CLASS(gootype, 0); PARAM_CLASS_OPT (gootype, AActor) { gootype = PClass::FindActor("PodGoo"); }
int count; int count;
int chance; int chance;
@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
chance = pr_podpain (); chance = pr_podpain ();
if (chance < 128) if (chance < 128)
{ {
return; return 0;
} }
for (count = chance > 240 ? 2 : 1; count; count--) 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->vely = pr_podpain.Random2() << 9;
goo->velz = FRACUNIT/2 + (pr_podpain() << 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) DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
if ( (mo = self->master)) if ( (mo = self->master) )
{ {
if (mo->special1 > 0) if (mo->special1 > 0)
{ {
mo->special1--; mo->special1--;
} }
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -94,8 +98,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
{ {
ACTION_PARAM_START(1); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_CLASS(podtype, 0); PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); }
AActor *mo; AActor *mo;
fixed_t x; fixed_t x;
@ -103,7 +107,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
if (self->special1 == MAX_GEN_PODS) if (self->special1 == MAX_GEN_PODS)
{ // Too many generated pods { // Too many generated pods
return; return 0;
} }
x = self->X(); x = self->X();
y = self->Y(); y = self->Y();
@ -111,14 +115,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
if (!P_CheckPosition (mo, x, y)) if (!P_CheckPosition (mo, x, y))
{ // Didn't fit { // Didn't fit
mo->Destroy (); mo->Destroy ();
return; return 0;
} }
mo->SetState (mo->FindState("Grow")); mo->SetState (mo->FindState("Grow"));
P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT)); P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE); S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE);
self->special1++; // Increment generated pod count self->special1++; // Increment generated pod count
mo->master = self; // Link the generator to the pod 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) DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
{ {
PARAM_ACTION_PROLOGUE;
if (++self->health > 35) if (++self->health > 35)
{ {
self->velz += self->velz/2; self->velz += self->velz/2;
} }
return 0;
} }
@ -144,7 +151,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet) DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
{ {
PARAM_ACTION_PROLOGUE;
self->tics = 105 + (pr_volcano() & 127); self->tics = 105 + (pr_volcano() & 127);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -155,6 +165,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
int count; int count;
AActor *blast; AActor *blast;
@ -174,6 +186,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM); S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
P_CheckMissileSpawn (blast, self->radius); P_CheckMissileSpawn (blast, self->radius);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -184,6 +197,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
{ {
PARAM_ACTION_PROLOGUE;
unsigned int i; unsigned int i;
AActor *tiny; AActor *tiny;
angle_t angle; angle_t angle;
@ -208,5 +223,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
tiny->velz = FRACUNIT + (pr_volcimpact() << 9); tiny->velz = FRACUNIT + (pr_volcimpact() << 9);
P_CheckMissileSpawn (tiny, self->radius); 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int slope; int slope;
player_t *player; player_t *player;
@ -68,20 +70,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
ACTION_PARAM_START(2); PARAM_INT (damage);
ACTION_PARAM_INT(damage, 0); PARAM_CLASS (puff, AActor);
ACTION_PARAM_CLASS(puff, 1);
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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 = self->angle;
angle += pr_sap.Random2() << 18; angle += pr_sap.Random2() << 18;
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
@ -92,6 +96,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
// turn to face target // turn to face target
self->angle = self->AngleTo(linetarget); self->angle = self->AngleTo(linetarget);
} }
return 0;
} }
@ -103,20 +108,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1) DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
angle_t pitch = P_BulletSlope(self); angle_t pitch = P_BulletSlope(self);
damage = 7+(pr_fgw()&7); 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"); P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1");
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
angle_t angle; angle_t angle;
int damage; int damage;
@ -145,20 +155,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
angle_t pitch = P_BulletSlope(self); angle_t pitch = P_BulletSlope(self);
velz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed, velz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed,
finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]); finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]);
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::FindClass("GoldWandFX2"), self->angle+(ANG45/8), velz); P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), velz);
angle = self->angle-(ANG45/8); angle = self->angle-(ANG45/8);
for(i = 0; i < 5; i++) for(i = 0; i < 5; i++)
{ {
@ -167,6 +177,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
angle += ((ANG45/8)*2)/4; angle += ((ANG45/8)*2)/4;
} }
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX1")); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1"));
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/10)); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindClass("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) DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2")); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"));
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle-(ANG45/10)); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle+(ANG45/10)); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/5)); P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5));
P_SpawnPlayerMissile (self, PClass::FindClass("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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
int randVal; int randVal;
fixed_t dist; fixed_t dist;
player_t *player; player_t *player;
const PClass *pufftype; PClassActor *pufftype;
AActor *linetarget; AActor *linetarget;
int actualdamage = 0; int actualdamage = 0;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
ACTION_PARAM_START(1); PARAM_INT(power);
ACTION_PARAM_INT(power, 0);
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT; player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT;
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3) * 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); damage = pr_gatk.HitDice (2);
dist = 4*MELEERANGE; dist = 4*MELEERANGE;
angle += pr_gatk.Random2() << 17; angle += pr_gatk.Random2() << 17;
pufftype = PClass::FindClass("GauntletPuff2"); pufftype = PClass::FindActor("GauntletPuff2");
} }
else else
{ {
damage = pr_gatk.HitDice (2); damage = pr_gatk.HitDice (2);
dist = MELEERANGE+1; dist = MELEERANGE+1;
angle += pr_gatk.Random2() << 18; angle += pr_gatk.Random2() << 18;
pufftype = PClass::FindClass("GauntletPuff1"); pufftype = PClass::FindActor("GauntletPuff1");
} }
slope = P_AimLineAttack (self, angle, dist, &linetarget); slope = P_AimLineAttack (self, angle, dist, &linetarget);
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage); 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; player->extralight = !player->extralight;
} }
S_Sound (self, CHAN_AUTO, "weapons/gauntletson", 1, ATTN_NORM); S_Sound (self, CHAN_AUTO, "weapons/gauntletson", 1, ATTN_NORM);
return; return 0;
} }
randVal = pr_gatk(); randVal = pr_gatk();
if (randVal < 64) if (randVal < 64)
@ -322,6 +340,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
self->angle += ANG90/20; self->angle += ANG90/20;
} }
self->flags |= MF_JUSTATTACKED; self->flags |= MF_JUSTATTACKED;
return 0;
} }
// --- Mace ----------------------------------------------------------------- // --- Mace -----------------------------------------------------------------
@ -404,33 +423,36 @@ void FireMacePL1B (AActor *actor)
DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
{ {
PARAM_ACTION_PROLOGUE;
AActor *ball; AActor *ball;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (pr_maceatk() < 28) if (pr_maceatk() < 28)
{ {
FireMacePL1B (self); FireMacePL1B (self);
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT; player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT;
player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*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)); self->angle+(((pr_maceatk()&7)-4)<<24));
if (ball) if (ball)
{ {
ball->special1 = 16; // tics till dropoff ball->special1 = 16; // tics till dropoff
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -441,14 +463,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check) DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
{ {
PARAM_ACTION_PROLOGUE;
if (self->special1 == 0) if (self->special1 == 0)
{ {
return; return 0;
} }
self->special1 -= 4; self->special1 -= 4;
if (self->special1 > 0) if (self->special1 > 0)
{ {
return; return 0;
} }
self->special1 = 0; self->special1 = 0;
self->flags &= ~MF_NOGRAVITY; self->flags &= ~MF_NOGRAVITY;
@ -467,6 +491,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
self->vely = (int)(self->vely * velscale); self->vely = (int)(self->vely * velscale);
#endif #endif
self->velz -= self->velz >> 1; self->velz -= self->velz >> 1;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -477,6 +502,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact) DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
{ {
PARAM_ACTION_PROLOGUE;
if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE)) if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE))
{ // Bounce { // Bounce
self->health = MAGIC_JUNK; self->health = MAGIC_JUNK;
@ -492,6 +519,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
self->gravity = FRACUNIT; self->gravity = FRACUNIT;
S_Sound (self, CHAN_BODY, "weapons/macehit", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *tiny; AActor *tiny;
angle_t angle; angle_t angle;
if ((self->Z() <= self->floorz) && P_HitFloor (self)) if ((self->Z() <= self->floorz) && P_HitFloor (self))
{ // Landed in some sort of liquid { // Landed in some sort of liquid
self->Destroy (); self->Destroy ();
return; return 0;
} }
if (self->flags & MF_INBOUNCE) if (self->flags & MF_INBOUNCE)
{ {
@ -549,6 +579,7 @@ boom:
self->BounceFlags = BOUNCE_None; self->BounceFlags = BOUNCE_None;
self->gravity = FRACUNIT; self->gravity = FRACUNIT;
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -559,20 +590,22 @@ boom:
DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2) DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &linetarget); mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &linetarget);
if (mo) if (mo)
@ -587,6 +620,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
} }
} }
S_Sound (self, CHAN_WEAPON, "weapons/maceshoot", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
AActor *target; AActor *target;
angle_t angle = 0; angle_t angle = 0;
@ -606,7 +642,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
if ((self->Z() <= self->floorz) && P_HitFloor (self)) if ((self->Z() <= self->floorz) && P_HitFloor (self))
{ // Landed in some sort of liquid { // Landed in some sort of liquid
self->Destroy (); self->Destroy ();
return; return 0;
} }
if (self->flags & MF_INBOUNCE) if (self->flags & MF_INBOUNCE)
{ {
@ -664,6 +700,7 @@ boom:
self->gravity = FRACUNIT; self->gravity = FRACUNIT;
S_Sound (self, CHAN_BODY, "weapons/maceexplode", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
angle_t pitch = P_BulletSlope(self); angle_t pitch = P_BulletSlope(self);
damage = pr_fb1.HitDice (4); 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"); P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff");
S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
{ {
PARAM_ACTION_PROLOGUE;
unsigned int i; unsigned int i;
angle_t angle; angle_t angle;
AActor *ripper; AActor *ripper;
@ -788,6 +830,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
ripper->vely = FixedMul (ripper->Speed, finesine[angle]); ripper->vely = FixedMul (ripper->Speed, finesine[angle]);
P_CheckMissileSpawn (ripper, self->radius); P_CheckMissileSpawn (ripper, self->radius);
} }
return 0;
} }
// --- Skull rod ------------------------------------------------------------ // --- Skull rod ------------------------------------------------------------
@ -860,26 +903,29 @@ void ARainTracker::Serialize (FArchive &arc)
DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1) DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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 // Randomize the first frame
if (mo && pr_fsr1() > 128) if (mo && pr_fsr1() > 128)
{ {
mo->SetState (mo->state->GetNextState()); mo->SetState (mo->state->GetNextState());
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -893,19 +939,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1)
DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2) DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
AActor *MissileActor; AActor *MissileActor;
AActor *linetarget; AActor *linetarget;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &linetarget, &MissileActor); P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &linetarget, &MissileActor);
// Use MissileActor instead of the return value from // 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
{ {
PARAM_ACTION_PROLOGUE;
ARainTracker *tracker; ARainTracker *tracker;
if (self->target == NULL || self->target->health <= 0) if (self->target == NULL || self->target->health <= 0)
{ // Shooter is dead or nonexistant { // Shooter is dead or nonexistant
return; return 0;
} }
tracker = self->target->FindInventory<ARainTracker> (); tracker = self->target->FindInventory<ARainTracker> ();
@ -977,6 +1028,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
tracker->Rain1 = self; tracker->Rain1 = self;
} }
self->special1 = S_FindSound ("misc/rain"); self->special1 = S_FindSound ("misc/rain");
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -987,6 +1039,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_AddPlayerRain)
DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
ARainTracker *tracker; ARainTracker *tracker;
@ -996,7 +1050,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
if (self->target == NULL) if (self->target == NULL)
{ // Player left the game { // Player left the game
self->Destroy (); self->Destroy ();
return; return 0;
} }
tracker = self->target->FindInventory<ARainTracker> (); tracker = self->target->FindInventory<ARainTracker> ();
if (tracker != NULL) if (tracker != NULL)
@ -1011,18 +1065,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
} }
} }
self->Destroy (); self->Destroy ();
return; return 0;
} }
if (pr_storm() < 25) if (pr_storm() < 25)
{ // Fudge rain frequency { // Fudge rain frequency
return; return 0;
} }
fixedvec2 pos = self->Vec2Offset( fixedvec2 pos = self->Vec2Offset(
((pr_storm()&127) - 64) * FRACUNIT, ((pr_storm()&127) - 64) * FRACUNIT,
((pr_storm()&127) - 64) * FRACUNIT); ((pr_storm()&127) - 64) * FRACUNIT);
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
// We used bouncecount to store the 3D floor index in A_HideInCeiling // We used bouncecount to store the 3D floor index in A_HideInCeiling
if (!mo) return; if (!mo) return 0;
fixed_t newz; fixed_t newz;
if (self->bouncecount >= 0 if (self->bouncecount >= 0
&& (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) && (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); 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) DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
{ {
PARAM_ACTION_PROLOGUE;
if (self->Z() > self->floorz) if (self->Z() > self->floorz)
{ {
self->SetState (self->FindState("NotFloor")); self->SetState (self->FindState("NotFloor"));
@ -1061,6 +1117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
{ {
P_HitFloor (self); P_HitFloor (self);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1071,6 +1128,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_RainImpact)
DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling) DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling)
{ {
PARAM_ACTION_PROLOGUE;
// We use bouncecount to store the 3D floor index // We use bouncecount to store the 3D floor index
fixed_t foo; fixed_t foo;
for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++) 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->SetZ(foo + 4*FRACUNIT, false);
self->bouncecount = i; self->bouncecount = i;
return; return 0;
} }
} }
self->bouncecount = -1; self->bouncecount = -1;
self->SetZ(self->ceilingz + 4*FRACUNIT, false); self->SetZ(self->ceilingz + 4*FRACUNIT, false);
return 0;
} }
// --- Phoenix Rod ---------------------------------------------------------- // --- Phoenix Rod ----------------------------------------------------------
@ -1170,25 +1230,28 @@ int APhoenixFX2::DoSpecialDamage (AActor *target, int damage, FName damagetype)
DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1) DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1)); P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1));
angle = self->angle + ANG180; angle = self->angle + ANG180;
angle >>= ANGLETOFINESHIFT; angle >>= ANGLETOFINESHIFT;
self->velx += FixedMul (4*FRACUNIT, finecosine[angle]); self->velx += FixedMul (4*FRACUNIT, finecosine[angle]);
self->vely += FixedMul (4*FRACUNIT, finesine[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) DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
{ {
PARAM_ACTION_PROLOGUE;
AActor *puff; AActor *puff;
angle_t angle; angle_t angle;
@ -1216,6 +1281,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
puff->velx = FixedMul (FRACUNIT*13/10, finecosine[angle]); puff->velx = FixedMul (FRACUNIT*13/10, finecosine[angle]);
puff->vely = FixedMul (FRACUNIT*13/10, finesine[angle]); puff->vely = FixedMul (FRACUNIT*13/10, finesine[angle]);
puff->velz = 0; puff->velz = 0;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1226,6 +1292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2) DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
{ {
PARAM_ACTION_PROLOGUE;
if (self->player != NULL) if (self->player != NULL)
{ {
APhoenixRod *flamethrower = static_cast<APhoenixRod *> (self->player->ReadyWeapon); APhoenixRod *flamethrower = static_cast<APhoenixRod *> (self->player->ReadyWeapon);
@ -1234,6 +1302,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
flamethrower->FlameCount = FLAME_THROWER_TICS; flamethrower->FlameCount = FLAME_THROWER_TICS;
} }
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1246,6 +1315,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_InitPhoenixPL2)
DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
angle_t angle; angle_t angle;
@ -1256,7 +1327,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
soundid = "weapons/phoenixpowshoot"; soundid = "weapons/phoenixpowshoot";
@ -1267,7 +1338,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
P_SetPsprite (player, ps_weapon, flamethrower->FindState("Powerdown")); P_SetPsprite (player, ps_weapon, flamethrower->FindState("Powerdown"));
player->refire = 0; player->refire = 0;
S_StopSound (self, CHAN_WEAPON); S_StopSound (self, CHAN_WEAPON);
return; return 0;
} }
angle = self->angle; angle = self->angle;
@ -1288,6 +1359,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM);
} }
P_CheckMissileSpawn (mo, self->radius); P_CheckMissileSpawn (mo, self->radius);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1298,19 +1370,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
DEFINE_ACTION_FUNCTION(AActor, A_ShutdownPhoenixPL2) DEFINE_ACTION_FUNCTION(AActor, A_ShutdownPhoenixPL2)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
S_StopSound (self, CHAN_WEAPON); S_StopSound (self, CHAN_WEAPON);
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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) DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd)
{ {
PARAM_ACTION_PROLOGUE;
self->velz += FRACUNIT*3/2; self->velz += FRACUNIT*3/2;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1332,6 +1410,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd)
DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff) DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff)
{ {
PARAM_ACTION_PROLOGUE;
self->velz += FRACUNIT*18/10; 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) DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
AActor *fire; AActor *fire;
AActor *baseFire; AActor *baseFire;
@ -81,7 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
target = self->target; target = self->target;
if (target == NULL) if (target == NULL)
{ {
return; return 0;
} }
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
@ -89,18 +91,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
int damage = pr_atk.HitDice (6); int damage = pr_atk.HitDice (6);
int newdam = P_DamageMobj (target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, target, self); P_TraceBleed (newdam > 0 ? newdam : damage, target, self);
return; return 0;
} }
dist = self->AproxDistance (target) > 8*64*FRACUNIT; dist = self->AproxDistance (target) > 8*64*FRACUNIT;
randAttack = pr_atk (); randAttack = pr_atk ();
if (randAttack < atkResolve1[dist]) if (randAttack < atkResolve1[dist])
{ // Ice ball { // 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); S_Sound (self, CHAN_BODY, "ironlich/attack2", 1, ATTN_NORM);
} }
else if (randAttack < atkResolve2[dist]) else if (randAttack < atkResolve2[dist])
{ // Fire column { // Fire column
baseFire = P_SpawnMissile (self, target, PClass::FindClass("HeadFX3")); baseFire = P_SpawnMissile (self, target, PClass::FindActor("HeadFX3"));
if (baseFire != NULL) if (baseFire != NULL)
{ {
baseFire->SetState (baseFire->FindState("NoGrow")); baseFire->SetState (baseFire->FindState("NoGrow"));
@ -116,7 +118,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
fire->velx = baseFire->velx; fire->velx = baseFire->velx;
fire->vely = baseFire->vely; fire->vely = baseFire->vely;
fire->velz = baseFire->velz; fire->velz = baseFire->velz;
fire->Damage = 0; fire->Damage = NULL;
fire->health = (i+1) * 2; fire->health = (i+1) * 2;
P_CheckMissileSpawn (fire, self->radius); 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
{ {
PARAM_ACTION_PROLOGUE;
self->health -= 3; self->health -= 3;
if (self->health < 0) if (self->health < 0)
{ {
self->velx = self->vely = self->velz = 0; self->velx = self->vely = self->velz = 0;
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
self->flags &= ~MF_MISSILE; self->flags &= ~MF_MISSILE;
return; return 0;
} }
if ((self->special2 -= 3) < 0) if ((self->special2 -= 3) < 0)
{ {
@ -160,9 +165,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
} }
if (self->tracer && self->tracer->flags&MF_SHADOW) if (self->tracer && self->tracer->flags&MF_SHADOW)
{ {
return; return 0;
} }
P_SeekerMissile (self, ANGLE_1*10, ANGLE_1*30); 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) DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
{ {
PARAM_ACTION_PROLOGUE;
unsigned int i; unsigned int i;
angle_t angle; angle_t angle;
AActor *shard; AActor *shard;
@ -189,6 +197,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
shard->velz = -FRACUNIT*6/10; shard->velz = -FRACUNIT*6/10;
P_CheckMissileSpawn (shard, self->radius); P_CheckMissileSpawn (shard, self->radius);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -199,6 +208,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow) DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
{ {
PARAM_ACTION_PROLOGUE;
self->health--; self->health--;
self->AddZ(9*FRACUNIT); self->AddZ(9*FRACUNIT);
if (self->health == 0) if (self->health == 0)
@ -206,5 +217,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
self->Damage = self->GetDefault()->Damage; self->Damage = self->GetDefault()->Damage;
self->SetState (self->FindState("NoGrow")); self->SetState (self->FindState("NoGrow"));
} }
return 0;
} }

View file

@ -21,6 +21,8 @@ static FRandom pr_knightatk ("KnightAttack");
DEFINE_ACTION_FUNCTION(AActor, A_DripBlood) DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
fixed_t xo = (pr_dripblood.Random2() << 11); fixed_t xo = (pr_dripblood.Random2() << 11);
@ -29,6 +31,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
mo->velx = pr_dripblood.Random2 () << 10; mo->velx = pr_dripblood.Random2 () << 10;
mo->vely = pr_dripblood.Random2 () << 10; mo->vely = pr_dripblood.Random2 () << 10;
mo->gravity = FRACUNIT/8; mo->gravity = FRACUNIT/8;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -39,9 +42,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack) DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
{ {
@ -49,16 +54,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
S_Sound (self, CHAN_BODY, "hknight/melee", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "hknight/melee", 1, ATTN_NORM);
return; return 0;
} }
// Throw axe // Throw axe
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->flags & MF_SHADOW || pr_knightatk () < 40) if (self->flags & MF_SHADOW || pr_knightatk () < 40)
{ // Red axe { // Red axe
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindClass("RedAxe")); P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("RedAxe"));
return; return 0;
} }
// Green axe // 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) DEFINE_ACTION_FUNCTION(AActor, A_GhostOff)
{ {
PARAM_ACTION_PROLOGUE;
self->RenderStyle = STYLE_Normal; self->RenderStyle = STYLE_Normal;
self->flags3 &= ~MF3_GHOST; self->flags3 &= ~MF3_GHOST;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -32,8 +35,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_GhostOff)
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1) DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1)
{ {
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self); A_FaceTarget (self);
CALL_ACTION(A_GhostOff, self); CALL_ACTION(A_GhostOff, self);
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -44,10 +50,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1)
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2) DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2)
{ {
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self); A_FaceTarget (self);
self->alpha = HR_SHADOW; self->alpha = HR_SHADOW;
self->RenderStyle = STYLE_Translucent; self->RenderStyle = STYLE_Translucent;
self->flags3 |= MF3_GHOST; self->flags3 |= MF3_GHOST;
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -58,12 +67,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2)
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
CALL_ACTION(A_GhostOff, self); CALL_ACTION(A_GhostOff, self);
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -71,13 +82,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
int damage = pr_wizatk3.HitDice (4); int damage = pr_wizatk3.HitDice (4);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); 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); mo = P_SpawnMissile (self, self->target, fx);
if (mo != NULL) if (mo != NULL)
{ {
P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->velz); P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->velz);
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) DEFINE_ACTION_FUNCTION(AActor, A_BatSpawnInit)
{ {
PARAM_ACTION_PROLOGUE;
self->special1 = 0; // Frequency count self->special1 = 0; // Frequency count
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn) DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int delta; int delta;
angle_t angle; angle_t angle;
// Countdown until next spawn // Countdown until next spawn
if (self->special1-- > 0) return; if (self->special1-- > 0) return 0;
self->special1 = self->args[0]; // Reset frequency count self->special1 = self->args[0]; // Reset frequency count
delta = self->args[1]; delta = self->args[1];
if (delta==0) delta=1; if (delta==0) delta=1;
angle = self->angle + (((pr_batspawn()%delta)-(delta>>1))<<24); 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) if (mo)
{ {
mo->args[0] = pr_batspawn()&63; // floatbob index 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->special2 = self->args[3]<<3; // Set lifetime
mo->target = self; mo->target = self;
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_BatMove) DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
{ {
PARAM_ACTION_PROLOGUE;
angle_t newangle; angle_t newangle;
if (self->special2 < 0) if (self->special2 < 0)
@ -86,4 +94,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
// Handle Z movement // Handle Z movement
self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]); self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]);
self->args[0] = (self->args[0]+3)&63; 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) DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -34,9 +36,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
int damage = pr_atk.HitDice (4); int damage = pr_atk.HitDice (4);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
self->special1 = (pr_atk() & 3) + 5; self->special1 = (pr_atk() & 3) + 5;
return 0;
} }
//============================================================================ //============================================================================
@ -48,20 +51,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2) DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
if (!self->target || !self->special1) if (!self->target || !self->special1)
{ {
self->special1 = 0; self->special1 = 0;
self->SetState (self->SeeState); 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) if (mo != NULL)
{ {
mo->tracer = self->target; mo->tracer = self->target;
} }
self->special1--; self->special1--;
return 0;
} }
//============================================================================ //============================================================================
@ -72,7 +78,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave) DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{ {
PARAM_ACTION_PROLOGUE;
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT); 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) DEFINE_ACTION_FUNCTION(AActor, A_BishopDecide)
{ {
PARAM_ACTION_PROLOGUE;
if (pr_decide() < 220) if (pr_decide() < 220)
{ {
return; return 0;
} }
else else
{ {
self->SetState (self->FindState ("Blur")); self->SetState (self->FindState ("Blur"));
} }
return 0;
} }
//============================================================================ //============================================================================
@ -101,6 +113,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDecide)
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur) DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
{ {
PARAM_ACTION_PROLOGUE;
self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
if (pr_doblur() < 120) if (pr_doblur() < 120)
{ {
@ -115,6 +129,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
P_ThrustMobj (self, self->angle, 11*FRACUNIT); P_ThrustMobj (self, self->angle, 11*FRACUNIT);
} }
S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
if (!--self->special1) if (!--self->special1)
@ -145,6 +162,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
{ {
mo->angle = self->angle; mo->angle = self->angle;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -155,10 +173,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
DEFINE_ACTION_FUNCTION(AActor, A_BishopChase) DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4; fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4;
self->special2 = (self->special2 + 4) & 63; self->special2 = (self->special2 + 4) & 63;
newz += finesine[self->special2 << BOBTOFINESHIFT] * 4; newz += finesine[self->special2 << BOBTOFINESHIFT] * 4;
self->SetZ(newz); self->SetZ(newz);
return 0;
} }
//============================================================================ //============================================================================
@ -169,6 +190,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff) DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE); mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE);
@ -176,6 +199,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
{ {
mo->velz = FRACUNIT/2; mo->velz = FRACUNIT/2;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -186,12 +210,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur) DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
if (pr_pain() < 64) if (pr_pain() < 64)
{ {
self->SetState (self->FindState ("Blur")); self->SetState (self->FindState ("Blur"));
return; return 0;
} }
fixed_t xo = (pr_pain.Random2() << 12); fixed_t xo = (pr_pain.Random2() << 12);
fixed_t yo = (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; 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; angle_t angle,ang;
AActor *mo; AActor *mo;
@ -97,13 +97,13 @@ enum
DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
{ {
ACTION_PARAM_START(6); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_INT (blastflags, 0); PARAM_INT_OPT (blastflags) { blastflags = 0; }
ACTION_PARAM_FIXED(strength, 1); PARAM_INT_OPT (strength) { strength = 255; }
ACTION_PARAM_FIXED(radius, 2); PARAM_INT_OPT (radius) { radius = 255; }
ACTION_PARAM_FIXED(speed, 3); PARAM_FIXED_OPT (speed) { speed = 20; }
ACTION_PARAM_CLASS(blasteffect, 4); PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); }
ACTION_PARAM_SOUND(blastsound, 5); PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; }
AActor *mo; AActor *mo;
TThinkerIterator<AActor> iterator; TThinkerIterator<AActor> iterator;
@ -111,15 +111,19 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON()) 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)) if (weapon != NULL && !weapon->DepleteAmmo(weapon->bAltFire))
return; {
return 0;
}
} }
S_Sound (self, CHAN_AUTO, blastsound, 1, ATTN_NORM); 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 ()) ) while ( (mo = iterator.Next ()) )
{ {
if ((mo == self) || ((mo->flags2 & MF2_BOSS) && !(blastflags & BF_AFFECTBOSSES)) 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)); 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) DEFINE_ACTION_FUNCTION(AActor, A_CentaurDefend)
{ {
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self); A_FaceTarget (self);
if (self->CheckMeleeRange() && pr_centaurdefend() < 32) if (self->CheckMeleeRange() && pr_centaurdefend() < 32)
{ {
@ -24,4 +26,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CentaurDefend)
self->flags2&=~(MF2_REFLECTIVE|MF2_INVULNERABLE); self->flags2&=~(MF2_REFLECTIVE|MF2_INVULNERABLE);
self->SetState (self->MeleeState); self->SetState (self->MeleeState);
} }
return 0;
} }

View file

@ -69,20 +69,23 @@ void ACFlameMissile::Effect ()
DEFINE_ACTION_FUNCTION(AActor, A_CFlameAttack) DEFINE_ACTION_FUNCTION(AActor, A_CFlameAttack)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACFlameMissile)); P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACFlameMissile));
S_Sound (self, CHAN_WEAPON, "ClericFlameFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE; self->renderflags &= ~RF_INVISIBLE;
self->velx = 0; self->velx = 0;
self->vely = 0; self->vely = 0;
self->velz = 0; self->velz = 0;
S_Sound (self, CHAN_BODY, "ClericFlameExplode", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
int an, an90; int an, an90;
fixed_t dist; fixed_t dist;
@ -150,6 +158,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
} }
self->SetState (self->SpawnState); self->SetState (self->SpawnState);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -160,10 +169,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate) DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate)
{ {
PARAM_ACTION_PROLOGUE;
int an; int an;
an = (self->angle+ANG90)>>ANGLETOFINESHIFT; an = (self->angle+ANG90)>>ANGLETOFINESHIFT;
self->velx = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]); self->velx = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]);
self->vely = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]); self->vely = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]);
self->angle += ANG90/15; 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) DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
{ {
PARAM_ACTION_PROLOGUE;
int j; int j;
int i; int i;
AActor *mo; AActor *mo;
@ -175,6 +177,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
} }
SpawnSpiritTail (mo); SpawnSpiritTail (mo);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -207,24 +210,30 @@ void SpawnSpiritTail (AActor *spirit)
DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon); ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon);
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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; weapon->CHolyCount = 3;
S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette)
{ {
PARAM_ACTION_PROLOGUE;
if (self->player != NULL) if (self->player != NULL)
{ {
ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon); ACWeapWraithverge *weapon = static_cast<ACWeapWraithverge *> (self->player->ReadyWeapon);
@ -243,6 +254,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette)
weapon->CHolyCount--; weapon->CHolyCount--;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -316,6 +328,8 @@ static void CHolyTailRemove (AActor *actor)
DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail) DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
{ {
PARAM_ACTION_PROLOGUE;
AActor *parent; AActor *parent;
parent = self->target; 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! if (parent == NULL || parent->health <= 0) // better check for health than current state - it's safer!
{ // Ghost removed, so remove all tail parts { // Ghost removed, so remove all tail parts
CHolyTailRemove (self); CHolyTailRemove (self);
return; return 0;
} }
else else
{ {
@ -335,6 +349,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
} }
CHolyTailFollow (self, 10*FRACUNIT); CHolyTailFollow (self, 10*FRACUNIT);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -471,6 +486,8 @@ void CHolyWeave (AActor *actor, FRandom &pr_random)
DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek) DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
{ {
PARAM_ACTION_PROLOGUE;
self->health--; self->health--;
if (self->health <= 0) if (self->health <= 0)
{ {
@ -479,7 +496,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
self->velz = 0; self->velz = 0;
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
self->tics -= pr_holyseek()&3; self->tics -= pr_holyseek()&3;
return; return 0;
} }
if (self->tracer) if (self->tracer)
{ {
@ -491,6 +508,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
} }
} }
CHolyWeave (self, pr_holyweave); CHolyWeave (self, pr_holyweave);
return 0;
} }
//============================================================================ //============================================================================
@ -501,6 +519,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream) DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_CHolySeek, self); CALL_ACTION(A_CHolySeek, self);
if (pr_checkscream() < 20) if (pr_checkscream() < 20)
{ {
@ -510,6 +530,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
{ {
CHolyFindTarget(self); CHolyFindTarget(self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -521,10 +542,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
DEFINE_ACTION_FUNCTION(AActor, A_ClericAttack) 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 if (missile != NULL) missile->tracer = NULL; // No initial target
S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
@ -26,9 +28,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
PClassActor *hammertime = PClass::FindActor("HammerPuff");
damage = 25+(pr_maceatk()&15); damage = 25+(pr_maceatk()&15);
for (i = 0; i < 16; i++) 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); slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
if (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) if (linetarget != NULL)
{ {
AdjustPlayerAngle (player->mo, linetarget); AdjustPlayerAngle (player->mo, linetarget);
@ -47,7 +51,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget); slope = P_AimLineAttack (player->mo, angle, 2*MELEERANGE, &linetarget);
if (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) if (linetarget != NULL)
{ {
AdjustPlayerAngle (player->mo, linetarget); AdjustPlayerAngle (player->mo, linetarget);
@ -60,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
angle = player->mo->angle; angle = player->mo->angle;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget); 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: 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) DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
{ {
PARAM_ACTION_PROLOGUE;
APlayerPawn *pmo; APlayerPawn *pmo;
int damage; int damage;
int newLife, max; int newLife, max;
@ -54,45 +56,47 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
int i; int i;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
PClassActor *puff;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
pmo = player->mo; pmo = player->mo;
damage = 20+(pr_staffcheck()&15); damage = 20+(pr_staffcheck()&15);
max = pmo->GetMaxHealth(); max = pmo->GetMaxHealth();
puff = PClass::FindActor("CStaffPuff");
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
angle = pmo->angle+i*(ANG45/16); angle = pmo->angle+i*(ANG45/16);
slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
if (linetarget) 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) if (linetarget != NULL)
{ {
pmo->angle = pmo->AngleTo(linetarget); 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)))) && (!(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); pmo->health = player->health = newLife;
newLife = newLife > max ? max : newLife; }
if (newLife > player->health)
{
pmo->health = player->health = newLife;
}
if (weapon != NULL) if (weapon != NULL)
{ {
FState * newstate = weapon->FindState("Drain"); FState * newstate = weapon->FindState("Drain");
if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate); 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; 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); slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
if (linetarget) 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) if (linetarget != NULL)
{ {
pmo->angle = pmo->AngleTo(linetarget); 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)
{ {
newLife = player->health+(damage>>4); newLife = player->health+(damage>>4);
newLife = newLife > max ? max : newLife; newLife = newLife > max ? max : newLife;
pmo->health = player->health = newLife; pmo->health = player->health = newLife;
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain")); P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
} }
if (weapon != NULL) if (weapon != NULL)
{ {
weapon->DepleteAmmo (weapon->bAltFire, false); weapon->DepleteAmmo (weapon->bAltFire, false);
@ -119,6 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
break; break;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -129,19 +134,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15)); mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15));
if (mo) if (mo)
@ -154,6 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
mo->WeaveIndexXY = 0; mo->WeaveIndexXY = 0;
} }
S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
{ {
PARAM_ACTION_PROLOGUE;
A_Weave(self, 3, 0, FRACUNIT, 0); 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) DEFINE_ACTION_FUNCTION(AActor, A_CStaffInitBlink)
{ {
PARAM_ACTION_PROLOGUE;
self->weaponspecial = (pr_blink()>>1)+20; self->weaponspecial = (pr_blink()>>1)+20;
return 0;
} }
//============================================================================ //============================================================================
@ -186,6 +200,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffInitBlink)
DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink)
{ {
PARAM_ACTION_PROLOGUE;
if (self->player && self->player->ReadyWeapon) if (self->player && self->player->ReadyWeapon)
{ {
if (!--self->weaponspecial) if (!--self->weaponspecial)
@ -198,4 +214,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink)
DoReadyWeapon(self); 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)) 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); S_Sound (actor, CHAN_WEAPON, actor->AttackSound, 1, ATTN_NORM);
} }
actor->target = oldTarget; actor->target = oldTarget;
@ -155,6 +155,8 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight) DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
{ {
PARAM_ACTION_PROLOGUE;
FActorIterator iterator (self->tid); FActorIterator iterator (self->tid);
do do
@ -163,10 +165,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
if (self->tracer == NULL) if (self->tracer == NULL)
{ {
self->SetState (self->SpawnState); self->SetState (self->SpawnState);
return; return 0;
} }
} while (self->tracer == self); } while (self->tracer == self);
self->RemoveFromHash (); self->RemoveFromHash ();
return 0;
} }
//============================================================================ //============================================================================
@ -177,6 +180,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonInitFlight)
DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1); DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1);
@ -185,7 +190,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
if(!(self->target->flags&MF_SHOOTABLE)) if(!(self->target->flags&MF_SHOOTABLE))
{ // target died { // target died
self->target = NULL; self->target = NULL;
return; return 0;
} }
angle = self->AngleTo(self->target); angle = self->AngleTo(self->target);
if (absangle(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange()) 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); P_LookForPlayers (self, true, NULL);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -215,6 +221,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap) DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_DragonFlight, self); CALL_ACTION(A_DragonFlight, self);
if (pr_dragonflap() < 240) if (pr_dragonflap() < 240)
{ {
@ -224,6 +232,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
{ {
self->PlayActiveSound (); self->PlayActiveSound ();
} }
return 0;
} }
//============================================================================ //============================================================================
@ -234,7 +243,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlap)
DEFINE_ACTION_FUNCTION(AActor, A_DragonAttack) 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) DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int i; int i;
int delay; int delay;
@ -262,7 +276,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
mo->tics = delay+(pr_dragonfx2()&3)*i*2; mo->tics = delay+(pr_dragonfx2()&3)*i*2;
mo->target = self->target; mo->target = self->target;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -273,11 +288,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
DEFINE_ACTION_FUNCTION(AActor, A_DragonPain) DEFINE_ACTION_FUNCTION(AActor, A_DragonPain)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_Pain, self); CALL_ACTION(A_Pain, self);
if (!self->tracer) if (!self->tracer)
{ // no destination spot yet { // no destination spot yet
self->SetState (self->SeeState); self->SetState (self->SeeState);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -288,8 +306,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonPain)
DEFINE_ACTION_FUNCTION(AActor, A_DragonCheckCrash) DEFINE_ACTION_FUNCTION(AActor, A_DragonCheckCrash)
{ {
PARAM_ACTION_PROLOGUE;
if (self->Z() <= self->floorz) if (self->Z() <= self->floorz)
{ {
self->SetState (self->FindState ("Crash")); self->SetState (self->FindState ("Crash"));
} }
return 0;
} }

View file

@ -68,11 +68,13 @@ FState *AFWeapAxe::GetAtkState (bool hold)
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (player->ReadyWeapon->Ammo1->Amount) if (player->ReadyWeapon->Ammo1->Amount)
{ {
@ -82,6 +84,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
{ {
DoReadyWeapon(self); DoReadyWeapon(self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -92,11 +95,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (player->ReadyWeapon->Ammo1->Amount <= 0) if (player->ReadyWeapon->Ammo1->Amount <= 0)
{ {
@ -106,6 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
{ {
DoReadyWeapon(self); DoReadyWeapon(self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -116,11 +122,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (player->ReadyWeapon->Ammo1->Amount) if (player->ReadyWeapon->Ammo1->Amount)
{ {
@ -130,6 +138,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
{ {
CALL_ACTION(A_Raise, self); CALL_ACTION(A_Raise, self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -140,11 +149,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (player->ReadyWeapon->Ammo1->Amount <= 0) if (player->ReadyWeapon->Ammo1->Amount <= 0)
{ {
@ -154,6 +165,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
{ {
CALL_ACTION(A_Raise, self); CALL_ACTION(A_Raise, self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -164,16 +176,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (player->ReadyWeapon->Ammo1->Amount) if (player->ReadyWeapon->Ammo1->Amount)
{ {
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow")); 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) DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
fixed_t power; fixed_t power;
int damage; int damage;
@ -192,12 +209,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
int useMana; int useMana;
player_t *player; player_t *player;
AWeapon *weapon; AWeapon *weapon;
const PClass *pufftype; PClassActor *pufftype;
AActor *linetarget; AActor *linetarget;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AActor *pmo=player->mo; AActor *pmo=player->mo;
@ -209,12 +226,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{ {
damage <<= 1; damage <<= 1;
power = 6*FRACUNIT; power = 6*FRACUNIT;
pufftype = PClass::FindClass ("AxePuffGlow"); pufftype = PClass::FindActor ("AxePuffGlow");
useMana = 1; useMana = 1;
} }
else else
{ {
pufftype = PClass::FindClass ("AxePuff"); pufftype = PClass::FindActor ("AxePuff");
useMana = 0; useMana = 0;
} }
for (i = 0; i < 16; i++) 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) DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
fixed_t power; fixed_t power;
@ -34,28 +36,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
int i; int i;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
PClassActor *hammertime;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AActor *pmo=player->mo; AActor *pmo=player->mo;
damage = 60+(pr_hammeratk()&63); damage = 60+(pr_hammeratk()&63);
power = 10*FRACUNIT; power = 10*FRACUNIT;
hammertime = PClass::FindActor("HammerPuff");
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
angle = pmo->angle + i*(ANG45/32); angle = pmo->angle + i*(ANG45/32);
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); 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) if (linetarget != NULL)
{ {
AdjustPlayerAngle(pmo, linetarget); 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 pmo->weaponspecial = false; // Don't throw a hammer
goto hammerdone; goto hammerdone;
@ -63,13 +67,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
} }
angle = pmo->angle-i*(ANG45/32); angle = pmo->angle-i*(ANG45/32);
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); 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) if (linetarget != NULL)
{ {
AdjustPlayerAngle(pmo, linetarget); 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);
} }
@ -81,7 +85,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
// didn't find any targets in meleerange, so set to throw out a hammer // didn't find any targets in meleerange, so set to throw out a hammer
angle = pmo->angle; angle = pmo->angle;
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); 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; pmo->weaponspecial = false;
} }
@ -97,7 +101,7 @@ hammerdone:
{ {
pmo->weaponspecial = false; pmo->weaponspecial = false;
} }
return; return 0;
} }
//============================================================================ //============================================================================
@ -108,27 +112,30 @@ hammerdone:
DEFINE_ACTION_FUNCTION(AActor, A_FHammerThrow) DEFINE_ACTION_FUNCTION(AActor, A_FHammerThrow)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
if (!player->mo->weaponspecial) if (!player->mo->weaponspecial)
{ {
return; return 0;
} }
AWeapon *weapon = player->ReadyWeapon; AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire, false)) 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) if (mo)
{ {
mo->special1 = 0; 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) static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
{ {
const PClass *pufftype; PClassActor *pufftype;
AActor *linetarget; AActor *linetarget;
int slope; int slope;
@ -70,11 +70,11 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
{ {
damage <<= 1; damage <<= 1;
power *= 3; power *= 3;
pufftype = PClass::FindClass ("HammerPuff"); pufftype = PClass::FindActor("HammerPuff");
} }
else else
{ {
pufftype = PClass::FindClass ("PunchPuff"); pufftype = PClass::FindActor("PunchPuff");
} }
P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget); P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
if (linetarget != NULL) 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) DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
{ {
PARAM_ACTION_PROLOGUE;
int damage; int damage;
fixed_t power; fixed_t power;
int i; int i;
@ -106,7 +108,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
APlayerPawn *pmo = player->mo; APlayerPawn *pmo = player->mo;
@ -120,10 +122,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
if (pmo->weaponspecial >= 3) if (pmo->weaponspecial >= 3)
{ {
pmo->weaponspecial = 0; 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); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM);
} }
return; return 0;
} }
} }
// didn't find any creatures, so try to strike any walls // didn't find any creatures, so try to strike any walls
@ -131,5 +133,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
AActor *linetarget; AActor *linetarget;
int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE, &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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
{ {
ACTION_PARAM_START(3); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_CLASS(p1, 0); PARAM_CLASS(p1, AActor);
ACTION_PARAM_CLASS(p2, 1); PARAM_CLASS(p2, AActor);
ACTION_PARAM_CLASS(p3, 2); PARAM_CLASS(p3, AActor);
for (int i = 0, j = 0, fineang = 0; i < 3; ++i) 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) if (cls)
{ {
AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE); 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) DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) 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, -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); 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, 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); P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/4);
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
for (i = 1+(pr_fswordflame()&3); i; 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); fixed_t zo = ((pr_fswordflame() - 128) << 11);
Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); 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) DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack)
{ {
if (!self->target) return; PARAM_ACTION_PROLOGUE;
if (!self->target) return 0;
angle_t angle = self->angle; 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/8, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0); P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0);
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); 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) void A_FiredSpawnRock (AActor *actor)
{ {
AActor *mo; AActor *mo;
const PClass *rtype; PClassActor *rtype;
switch (pr_firedemonrock() % 5) switch (pr_firedemonrock() % 5)
{ {
case 0: case 0:
rtype = PClass::FindClass ("FireDemonRock1"); rtype = PClass::FindActor("FireDemonRock1");
break; break;
case 1: case 1:
rtype = PClass::FindClass ("FireDemonRock2"); rtype = PClass::FindActor("FireDemonRock2");
break; break;
case 2: case 2:
rtype = PClass::FindClass ("FireDemonRock3"); rtype = PClass::FindActor("FireDemonRock3");
break; break;
case 3: case 3:
rtype = PClass::FindClass ("FireDemonRock4"); rtype = PClass::FindActor("FireDemonRock4");
break; break;
case 4: case 4:
default: default:
rtype = PClass::FindClass ("FireDemonRock5"); rtype = PClass::FindActor("FireDemonRock5");
break; break;
} }
@ -80,11 +80,14 @@ void A_FiredSpawnRock (AActor *actor)
DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks) DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks)
{ {
PARAM_ACTION_PROLOGUE;
A_FiredSpawnRock (self); A_FiredSpawnRock (self);
A_FiredSpawnRock (self); A_FiredSpawnRock (self);
A_FiredSpawnRock (self); 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) DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
{ {
PARAM_ACTION_PROLOGUE;
// give some more velocity (x,y,&z) // give some more velocity (x,y,&z)
self->SetZ(self->floorz + FRACUNIT); self->SetZ(self->floorz + FRACUNIT);
self->velz = (2*FRACUNIT) + (pr_smbounce() << 10); self->velz = (2*FRACUNIT) + (pr_smbounce() << 10);
self->velx = pr_smbounce()%3<<FRACBITS; self->velx = pr_smbounce()%3<<FRACBITS;
self->vely = 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) DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (self->target == NULL) if (self->target == NULL)
return; return 0;
AActor *mo = P_SpawnMissile (self, self->target, PClass::FindClass ("FireDemonMissile")); AActor *mo = P_SpawnMissile (self, self->target, PClass::FindActor("FireDemonMissile"));
if (mo) S_Sound (self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{ {
PARAM_ACTION_PROLOGUE;
int weaveindex = self->special1; int weaveindex = self->special1;
AActor *target = self->target; AActor *target = self->target;
angle_t ang; angle_t ang;
@ -145,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
if(!self->target || !(self->target->flags&MF_SHOOTABLE)) if(!self->target || !(self->target->flags&MF_SHOOTABLE))
{ // Invalid target { // Invalid target
P_LookForPlayers (self,true, NULL); P_LookForPlayers (self,true, NULL);
return; return 0;
} }
// Strafe // Strafe
@ -193,7 +204,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{ {
self->SetState (self->MissileState); self->SetState (self->MissileState);
self->flags |= MF_JUSTATTACKED; self->flags |= MF_JUSTATTACKED;
return; return 0;
} }
} }
else else
@ -206,6 +217,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{ {
self->PlayActiveSound (); self->PlayActiveSound ();
} }
return 0;
} }
//============================================================================ //============================================================================
@ -216,6 +228,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch) DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE); mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE);
@ -232,4 +246,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
mo->vely = (pr_firedemonsplotch() - 128) << 11; mo->vely = (pr_firedemonsplotch() - 128) << 11;
mo->velz = (pr_firedemonsplotch() << 10) + FRACUNIT*3; mo->velz = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
} }
return 0;
} }

View file

@ -24,15 +24,6 @@ DECLARE_ACTION(A_CheckThrowBomb)
// Poison Bag Artifact (Flechette) ------------------------------------------ // 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) IMPLEMENT_CLASS (AArtiPoisonBag)
// Poison Bag 1 (The Cleric's) ---------------------------------------------- // Poison Bag 1 (The Cleric's) ----------------------------------------------
@ -155,10 +146,10 @@ IMPLEMENT_CLASS (AArtiPoisonBagGiver)
bool AArtiPoisonBagGiver::Use (bool pickup) bool AArtiPoisonBagGiver::Use (bool pickup)
{ {
const PClass *MissileType = PClass::FindClass((ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None)); PClassActor *missiletype = PClass::FindActor(this->GetClass()->MissileName);
if (MissileType != NULL) if (missiletype != NULL)
{ {
AActor *mo = Spawn (MissileType, Owner->Pos(), ALLOW_REPLACE); AActor *mo = Spawn (missiletype, Owner->Pos(), ALLOW_REPLACE);
if (mo != NULL) if (mo != NULL)
{ {
if (mo->IsKindOf(RUNTIME_CLASS(AInventory))) if (mo->IsKindOf(RUNTIME_CLASS(AInventory)))
@ -186,10 +177,10 @@ IMPLEMENT_CLASS (AArtiPoisonBagShooter)
bool AArtiPoisonBagShooter::Use (bool pickup) bool AArtiPoisonBagShooter::Use (bool pickup)
{ {
const PClass *MissileType = PClass::FindClass((ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None)); PClassActor *missiletype = PClass::FindActor(this->GetClass()->MissileName);
if (MissileType != NULL) if (missiletype != NULL)
{ {
AActor *mo = P_SpawnPlayerMissile(Owner, MissileType); AActor *mo = P_SpawnPlayerMissile(Owner, missiletype);
if (mo != NULL) if (mo != NULL)
{ {
// automatic handling of seeker missiles // 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))) if (other->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
{ {
spawntype = static_cast<APlayerPawn*>(other)->FlechetteType; spawntype = static_cast<APlayerPawn*>(other)->FlechetteType;
@ -273,8 +264,7 @@ AInventory *AArtiPoisonBag::CreateCopy (AActor *other)
} }
AInventory *copy; AInventory *copy;
PClassActor *spawntype = GetFlechetteType(other);
const PClass *spawntype = GetFlechetteType(other);
copy = static_cast<AInventory *>(Spawn (spawntype, 0, 0, 0, NO_REPLACE)); copy = static_cast<AInventory *>(Spawn (spawntype, 0, 0, 0, NO_REPLACE));
copy->Amount = Amount; copy->Amount = Amount;
copy->MaxAmount = MaxAmount; copy->MaxAmount = MaxAmount;
@ -353,7 +343,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
damage = FixedMul(damage, victim->DamageFactor); damage = FixedMul(damage, victim->DamageFactor);
if (damage > 0) if (damage > 0)
{ {
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->ActorInfo->DamageFactors); damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->DamageFactors);
} }
if (damage > 0) if (damage > 0)
{ {
@ -382,6 +372,8 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit) DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn<APoisonCloud> (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE); mo = Spawn<APoisonCloud> (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE);
@ -389,6 +381,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
{ {
mo->target = self->target; mo->target = self->target;
} }
return 0;
} }
//=========================================================================== //===========================================================================
@ -399,14 +392,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagCheck) DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagCheck)
{ {
PARAM_ACTION_PROLOGUE;
if (--self->special1 <= 0) if (--self->special1 <= 0)
{ {
self->SetState (self->FindState ("Death")); self->SetState (self->FindState ("Death"));
} }
else else
{ {
return; return 0;
} }
return 0;
} }
//=========================================================================== //===========================================================================
@ -417,12 +413,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagCheck)
DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage) DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
{ {
PARAM_ACTION_PROLOGUE;
int bobIndex; int bobIndex;
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE); P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE);
bobIndex = self->special2; bobIndex = self->special2;
self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1); self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1);
self->special2 = (bobIndex + 1) & 63; self->special2 = (bobIndex + 1) & 63;
return 0;
} }
//=========================================================================== //===========================================================================
@ -433,10 +432,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb) DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb)
{ {
PARAM_ACTION_PROLOGUE;
if (--self->health <= 0) if (--self->health <= 0)
{ {
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
} }
return 0;
} }
//=========================================================================== //===========================================================================
@ -447,6 +449,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb)
DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2) DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
{ {
PARAM_ACTION_PROLOGUE;
// [RH] Check using actual velocity, although the velz < 2 check still stands // [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 //if (abs(self->velx) < FRACUNIT*3/2 && abs(self->vely) < FRACUNIT*3/2
// && self->velz < 2*FRACUNIT) // && self->velz < 2*FRACUNIT)
@ -461,4 +465,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
self->flags &= ~MF_MISSILE; self->flags &= ~MF_MISSILE;
} }
CALL_ACTION(A_CheckThrowBomb, self); 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 // 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, // 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. // but at least we aren't crippled on maps with lots of stuff going on.
PARAM_ACTION_PROLOGUE;
validcount++; validcount++;
AActor *other = FindCorpse(self, self->Sector, 5); AActor *other = FindCorpse(self, self->Sector, 5);
if (other != NULL) if (other != NULL)
@ -67,16 +69,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlySearch)
self->target = other; self->target = other;
self->SetState(self->FindState("Buzz")); self->SetState(self->FindState("Buzz"));
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz) DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
{ {
PARAM_ACTION_PROLOGUE;
AActor *targ = self->target; AActor *targ = self->target;
if (targ == NULL || !(targ->flags & MF_CORPSE) || pr_fly() < 5) if (targ == NULL || !(targ->flags & MF_CORPSE) || pr_fly() < 5)
{ {
self->SetIdle(); self->SetIdle();
return; return 0;
} }
angle_t ang = self->AngleTo(targ); 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)) if (!P_TryMove(self, self->X() + 6 * finecosine[ang], self->Y() + 6 * finesine[ang], true))
{ {
self->SetIdle(true); self->SetIdle(true);
return; return 0;
} }
if (self->args[0] & 2) 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
{ {
PARAM_ACTION_PROLOGUE;
static const char *fogs[3] = static const char *fogs[3] =
{ {
"FogPatchSmall", "FogPatchSmall",
@ -34,11 +36,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
"FogPatchLarge" "FogPatchLarge"
}; };
AActor *mo=NULL; AActor *mo = NULL;
angle_t delta; angle_t delta;
if (self->special1-- > 0) return; if (self->special1-- > 0)
{
return 0;
}
self->special1 = self->args[2]; // Reset frequency count self->special1 = self->args[2]; // Reset frequency count
mo = Spawn (fogs[pr_fogspawn()%3], self->Pos(), ALLOW_REPLACE); 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->args[4] = 1; // Set to moving
mo->special2 = pr_fogspawn()&63; mo->special2 = pr_fogspawn()&63;
} }
return 0;
} }
//========================================================================== //==========================================================================
@ -65,16 +70,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
DEFINE_ACTION_FUNCTION(AActor, A_FogMove) DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
{ {
PARAM_ACTION_PROLOGUE;
int speed = self->args[0]<<FRACBITS; int speed = self->args[0]<<FRACBITS;
angle_t angle; angle_t angle;
int weaveindex; int weaveindex;
if (!(self->args[4])) return; if (!self->args[4])
{
return 0;
}
if (self->args[3]-- <= 0) if (self->args[3]-- <= 0)
{ {
self->SetState (self->FindState(NAME_Death), true); self->SetState (self->FindState(NAME_Death), true);
return; return 0;
} }
if ((self->args[3] % 4) == 0) if ((self->args[3] % 4) == 0)
@ -87,5 +97,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
angle = self->angle>>ANGLETOFINESHIFT; angle = self->angle>>ANGLETOFINESHIFT;
self->velx = FixedMul(speed, finecosine[angle]); self->velx = FixedMul(speed, finecosine[angle]);
self->vely = FixedMul(speed, finesine[angle]); self->vely = FixedMul(speed, finesine[angle]);
return 0;
} }

View file

@ -30,7 +30,12 @@ IMPLEMENT_CLASS (AArtiHealingRadius)
bool AArtiHealingRadius::Use (bool pickup) bool AArtiHealingRadius::Use (bool pickup)
{ {
bool effective = false; 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) for (int i = 0; i < MAXPLAYERS; ++i)
{ {
@ -65,8 +70,8 @@ bool AArtiHealingRadius::Use (bool pickup)
{ {
int amount = 50 + (pr_healradius() % 50); int amount = 50 + (pr_healradius() % 50);
if (players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana1), amount) || if (players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana1)), amount) ||
players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana2), amount)) players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana2)), amount))
{ {
gotsome = true; gotsome = true;
} }

View file

@ -231,6 +231,8 @@ void ASorcBall1::DoFireSpell ()
DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
self->SpawnState += 2; // [RH] Don't spawn balls again self->SpawnState += 2; // [RH] Don't spawn balls again
@ -252,6 +254,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
if (mo) mo->target = self; if (mo) mo->target = self;
mo = Spawn("SorcBall3", pos, NO_REPLACE); mo = Spawn("SorcBall3", pos, NO_REPLACE);
if (mo) mo->target = self; if (mo) mo->target = self;
return 0;
} }
@ -263,11 +266,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
{ {
PARAM_ACTION_PROLOGUE;
// [RH] If no parent, then die instead of crashing // [RH] If no parent, then die instead of crashing
if (self->target == NULL) if (self->target == NULL)
{ {
self->SetState (self->FindState(NAME_Pain)); self->SetState (self->FindState(NAME_Pain));
return; return 0;
} }
ASorcBall *actor; ASorcBall *actor;
@ -279,14 +284,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall))) 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); actor = static_cast<ASorcBall *> (self);
if (actor->target->health <= 0) if (actor->target->health <= 0)
{ {
actor->SetState (actor->FindState(NAME_Pain)); actor->SetState (actor->FindState(NAME_Pain));
return; return 0;
} }
baseangle = (angle_t)parent->special1; baseangle = (angle_t)parent->special1;
@ -311,7 +316,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
break; break;
case SORC_STOPPING: // Balls stopping case SORC_STOPPING: // Balls stopping
if ((parent->StopBall == RUNTIME_TYPE(actor)) && if ((parent->StopBall == actor->GetClass()) &&
(parent->args[1] > SORCBALL_SPEED_ROTATIONS) && (parent->args[1] > SORCBALL_SPEED_ROTATIONS) &&
(absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5))) (absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5)))
{ {
@ -328,7 +333,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
break; break;
case SORC_FIRESPELL: // Casting spell case SORC_FIRESPELL: // Casting spell
if (parent->StopBall == RUNTIME_TYPE(actor)) if (parent->StopBall == actor->GetClass())
{ {
// Put sorcerer into special throw spell anim // Put sorcerer into special throw spell anim
if (parent->health > 0) if (parent->health > 0)
@ -339,7 +344,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
break; break;
case SORC_FIRING_SPELL: case SORC_FIRING_SPELL:
if (parent->StopBall == RUNTIME_TYPE(actor)) if (parent->StopBall == actor->GetClass())
{ {
if (actor->special2-- <= 0) if (actor->special2-- <= 0)
{ {
@ -377,6 +382,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
actor->SetOrigin (pos, true); actor->SetOrigin (pos, true);
actor->floorz = parent->floorz; actor->floorz = parent->floorz;
actor->ceilingz = parent->ceilingz; actor->ceilingz = parent->ceilingz;
return 0;
} }
//============================================================================ //============================================================================
@ -389,8 +395,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls) DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls)
{ {
PARAM_ACTION_PROLOGUE;
self->args[3] = SORC_ACCELERATE; // speed mode self->args[3] = SORC_ACCELERATE; // speed mode
self->args[2] = SORCBALL_TERMINAL_SPEED; // target speed self->args[2] = SORCBALL_TERMINAL_SPEED; // target speed
return 0;
} }
@ -566,7 +575,7 @@ void ASorcBall3::CastSorcererSpell ()
ang1 = angle - ANGLE_45; ang1 = angle - ANGLE_45;
ang2 = angle + ANGLE_45; ang2 = angle + ANGLE_45;
const PClass *cls = PClass::FindClass("SorcFX3"); PClassActor *cls = PClass::FindActor("SorcFX3");
if (health < (SpawnHealth()/3)) if (health < (SpawnHealth()/3))
{ // Spawn 2 at a time { // Spawn 2 at a time
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT);
@ -615,7 +624,7 @@ void ASorcBall1::CastSorcererSpell ()
ang1 = angle + ANGLE_1*70; ang1 = angle + ANGLE_1*70;
ang2 = 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); mo = P_SpawnMissileAngle (parent, cls, ang1, 0);
if (mo) if (mo)
{ {
@ -662,7 +671,7 @@ void A_SorcOffense2(AActor *actor)
delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; delta = (finesine[index])*SORCFX4_SPREAD_ANGLE;
delta = (delta>>FRACBITS)*ANGLE_1; delta = (delta>>FRACBITS)*ANGLE_1;
ang1 = actor->angle + delta; ang1 = actor->angle + delta;
mo = P_SpawnMissileAngle(parent, PClass::FindClass("SorcFX4"), ang1, 0); mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0);
if (mo) if (mo)
{ {
mo->special2 = 35*5/2; // 5 seconds mo->special2 = 35*5/2; // 5 seconds
@ -682,8 +691,11 @@ void A_SorcOffense2(AActor *actor)
DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack) DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
{ {
PARAM_ACTION_PROLOGUE;
self->args[3] = SORC_ACCELERATE; self->args[3] = SORC_ACCELERATE;
self->args[2] = SORCBALL_INITIAL_SPEED; self->args[2] = SORCBALL_INITIAL_SPEED;
return 0;
} }
//============================================================================ //============================================================================
@ -696,6 +708,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle) DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t dist = 5*FRACUNIT; fixed_t dist = 5*FRACUNIT;
fixed_t speed = self->Speed; fixed_t speed = self->Speed;
angle_t rangle; angle_t rangle;
@ -714,6 +727,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
mo->velz = FRACUNIT*2; mo->velz = FRACUNIT*2;
} }
} }
return 0;
} }
@ -727,8 +741,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek) DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
{ {
PARAM_ACTION_PROLOGUE;
A_DoBounceCheck (self, "SorcererHeadScream"); A_DoBounceCheck (self, "SorcererHeadScream");
P_SeekerMissile (self,ANGLE_1*2,ANGLE_1*6); 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 // Split ball in two
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split) DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE); mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE);
@ -769,6 +788,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
mo->SetState (mo->FindState("Orbit")); mo->SetState (mo->FindState("Orbit"));
} }
self->Destroy (); self->Destroy ();
return 0;
} }
//============================================================================ //============================================================================
@ -781,6 +801,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
fixedvec3 pos; fixedvec3 pos;
AActor *parent = self->target; AActor *parent = self->target;
@ -789,7 +811,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
if (parent == NULL) if (parent == NULL)
{ {
self->Destroy(); self->Destroy();
return; return 0;
} }
fixed_t dist = parent->radius; fixed_t dist = parent->radius;
@ -839,6 +861,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
self->SetOrigin (pos, true); self->SetOrigin (pos, true);
self->floorz = parent->floorz; self->floorz = parent->floorz;
self->ceilingz = parent->ceilingz; self->ceilingz = parent->ceilingz;
return 0;
} }
//============================================================================ //============================================================================
@ -851,6 +874,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop) DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = Spawn("Bishop", self->Pos(), ALLOW_REPLACE); mo = Spawn("Bishop", self->Pos(), ALLOW_REPLACE);
if (mo) if (mo)
@ -867,6 +892,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
} }
} }
self->Destroy (); self->Destroy ();
return 0;
} }
//============================================================================ //============================================================================
@ -877,8 +903,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop)
DEFINE_ACTION_FUNCTION(AActor, A_SorcererBishopEntry) DEFINE_ACTION_FUNCTION(AActor, A_SorcererBishopEntry)
{ {
PARAM_ACTION_PROLOGUE;
Spawn("SorcFX3Explosion", self->Pos(), ALLOW_REPLACE); Spawn("SorcFX3Explosion", self->Pos(), ALLOW_REPLACE);
S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_SorcFX4Check)
{ {
PARAM_ACTION_PROLOGUE;
if (self->special2-- <= 0) if (self->special2-- <= 0)
{ {
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
} }
return 0;
} }
//============================================================================ //============================================================================
@ -907,6 +939,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX4Check)
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop) DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
{ {
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE); S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE);
self->flags &= ~MF_NOGRAVITY; self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT/8; self->gravity = FRACUNIT/8;
@ -916,6 +950,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
self->special2 = 4*FRACUNIT; // Initial bounce factor self->special2 = 4*FRACUNIT; // Initial bounce factor
self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit
self->args[3] = 5; // Bounce time in seconds 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) DEFINE_ACTION_FUNCTION(AActor, A_BounceCheck)
{ {
PARAM_ACTION_PROLOGUE;
A_DoBounceCheck (self, "SorcererBigBallExplode"); A_DoBounceCheck (self, "SorcererBigBallExplode");
return 0;
} }

View file

@ -29,4 +29,13 @@ class AMageWeapon : public AWeapon
public: public:
}; };
class AArtiPoisonBag : public AInventory
{
DECLARE_CLASS (AArtiPoisonBag, AInventory)
public:
bool HandlePickup (AInventory *item);
AInventory *CreateCopy (AActor *other);
void BeginPlay ();
};
#endif //__A_HEXENGLOBAL_H__ #endif //__A_HEXENGLOBAL_H__

View file

@ -55,6 +55,8 @@ void APottery1::HitFloor ()
DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode) DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo = NULL; AActor *mo = NULL;
int i; int i;
@ -71,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
} }
S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM); S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM);
// Spawn an item? // Spawn an item?
const PClass *type = P_GetSpawnableType(self->args[0]); PClassActor *type = P_GetSpawnableType(self->args[0]);
if (type != NULL) if (type != NULL)
{ {
if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) 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); Spawn (type, self->Pos(), ALLOW_REPLACE);
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -90,8 +93,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
DEFINE_ACTION_FUNCTION(AActor, A_PotteryChooseBit) DEFINE_ACTION_FUNCTION(AActor, A_PotteryChooseBit)
{ {
PARAM_ACTION_PROLOGUE;
self->SetState (self->FindState(NAME_Death) + 1 + 2*(pr_bit()%5)); self->SetState (self->FindState(NAME_Death) + 1 + 2*(pr_bit()%5));
self->tics = 256+(pr_bit()<<1); self->tics = 256+(pr_bit()<<1);
return 0;
} }
//============================================================================ //============================================================================
@ -102,6 +108,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryChooseBit)
DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck) DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
for(i = 0; i < MAXPLAYERS; 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)) if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self) - pmo->angle) <= ANGLE_45))
{ // Previous state (pottery bit waiting state) { // Previous state (pottery bit waiting state)
self->SetState (self->state - 1); self->SetState (self->state - 1);
return; return 0;
} }
} }
} }
return 0;
} }
// Lynched corpse (no heart) ------------------------------------------------ // Lynched corpse (no heart) ------------------------------------------------
@ -143,10 +152,13 @@ void AZCorpseLynchedNoHeart::PostBeginPlay ()
DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip) DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip)
{ {
PARAM_ACTION_PROLOGUE;
if (pr_drip() <= 128) if (pr_drip() <= 128)
{ {
Spawn ("CorpseBloodDrip", self->PosPlusZ(self->height/2), ALLOW_REPLACE); 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) DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int i; int i;
@ -182,6 +196,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
} }
S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE); S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE);
self->Destroy (); self->Destroy ();
return 0;
} }
//============================================================================ //============================================================================
@ -192,6 +207,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn) DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int i; int i;
@ -200,7 +217,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
fixed_t xo = (pr_leaf.Random2() << 14); fixed_t xo = (pr_leaf.Random2() << 14);
fixed_t yo = (pr_leaf.Random2() << 14); fixed_t yo = (pr_leaf.Random2() << 14);
fixed_t zo = (pr_leaf() << 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); self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
@ -210,6 +227,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
mo->special1 = 0; mo->special1 = 0;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -220,10 +238,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust) DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust)
{ {
PARAM_ACTION_PROLOGUE;
if (pr_leafthrust() <= 96) if (pr_leafthrust() <= 96)
{ {
self->velz += (pr_leafthrust()<<9)+FRACUNIT; self->velz += (pr_leafthrust()<<9)+FRACUNIT;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -234,11 +255,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust)
DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck) DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
{ {
PARAM_ACTION_PROLOGUE;
self->special1++; self->special1++;
if (self->special1 >= 20) if (self->special1 >= 20)
{ {
self->SetState (NULL); self->SetState (NULL);
return; return 0;
} }
angle_t ang = self->target ? self->target->angle : self->angle; angle_t ang = self->target ? self->target->angle : self->angle;
if (pr_leafcheck() > 64) if (pr_leafcheck() > 64)
@ -247,12 +270,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
{ {
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT); P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT);
} }
return; return 0;
} }
self->SetState (self->SpawnState + 7); self->SetState (self->SpawnState + 7);
self->velz = (pr_leafcheck()<<9)+FRACUNIT; self->velz = (pr_leafcheck()<<9)+FRACUNIT;
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT); P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT);
self->flags |= MF_MISSILE; self->flags |= MF_MISSILE;
return 0;
} }
//=========================================================================== //===========================================================================
@ -263,7 +287,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom) DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
{ {
PARAM_ACTION_PROLOGUE;
self->tics = 128+(pr_shroom()<<1); self->tics = 128+(pr_shroom()<<1);
return 0;
} }
//=========================================================================== //===========================================================================
@ -274,6 +301,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode) DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int i; int i;
@ -292,7 +321,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
} }
} }
// Spawn an item? // Spawn an item?
const PClass *type = P_GetSpawnableType(self->args[0]); PClassActor *type = P_GetSpawnableType(self->args[0]);
if (type != NULL) if (type != NULL)
{ {
if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) 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); S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_NORM);
self->Destroy (); self->Destroy ();
return 0;
} }
// Bell --------------------------------------------------------------------- // Bell ---------------------------------------------------------------------
@ -332,6 +362,8 @@ void AZBell::Activate (AActor *activator)
DEFINE_ACTION_FUNCTION(AActor, A_BellReset1) DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
{ {
PARAM_ACTION_PROLOGUE;
self->flags |= MF_NOGRAVITY; self->flags |= MF_NOGRAVITY;
self->height <<= 2; self->height <<= 2;
if (self->special) 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->args[1], self->args[2], self->args[3], self->args[4]);
self->special = 0; self->special = 0;
} }
return 0;
} }
//=========================================================================== //===========================================================================
@ -350,9 +383,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
DEFINE_ACTION_FUNCTION(AActor, A_BellReset2) DEFINE_ACTION_FUNCTION(AActor, A_BellReset2)
{ {
PARAM_ACTION_PROLOGUE;
self->flags |= MF_SHOOTABLE; self->flags |= MF_SHOOTABLE;
self->flags &= ~MF_CORPSE; self->flags &= ~MF_CORPSE;
self->flags6 &= ~MF6_KILLED; self->flags6 &= ~MF6_KILLED;
self->health = 5; self->health = 5;
return 0;
} }

View file

@ -26,6 +26,8 @@ static const char *WispTypes[2] =
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t dist; fixed_t dist;
fixed_t an; fixed_t an;
@ -40,6 +42,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
FixedMul(dist, finesine[an]), FixedMul(dist, finesine[an]),
60 * FRACUNIT), ALLOW_REPLACE); 60 * FRACUNIT), ALLOW_REPLACE);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -50,11 +53,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
{ {
PARAM_ACTION_PROLOGUE;
fixed_t dist; fixed_t dist;
fixed_t an; fixed_t an;
AActor *mo; AActor *mo;
A_Chase (self); A_Chase (stack, self);
if (pr_iceguychase() < 128) if (pr_iceguychase() < 128)
{ {
dist = ((pr_iceguychase()-128)*self->radius)>>7; dist = ((pr_iceguychase()-128)*self->radius)>>7;
@ -72,6 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
mo->target = self; mo->target = self;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -82,13 +88,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack)
{ {
PARAM_ACTION_PROLOGUE;
if(!self->target) 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::FindActor ("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"));
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie)
{ {
PARAM_ACTION_PROLOGUE;
self->velx = 0; self->velx = 0;
self->vely = 0; self->vely = 0;
self->velz = 0; self->velz = 0;
self->height = self->GetDefault()->height; self->height = self->GetDefault()->height;
CALL_ACTION(A_FreezeDeathChunks, self); CALL_ACTION(A_FreezeDeathChunks, self);
return 0;
} }
//============================================================================ //============================================================================
@ -114,17 +126,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie)
DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
unsigned int i; unsigned int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
mo = P_SpawnMissileAngleZ (self, self->Z()+3*FRACUNIT, 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) if (mo)
{ {
mo->target = self->target; mo->target = self->target;
} }
} }
return 0;
} }

View file

@ -74,10 +74,10 @@ void A_KSpiritRoam (AActor *);
void A_KBolt (AActor *); void A_KBolt (AActor *);
void A_KBoltRaise (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); void KSpiritInit (AActor *spirit, AActor *korax);
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, 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); extern void SpawnSpiritTail (AActor *spirit);
@ -89,6 +89,8 @@ extern void SpawnSpiritTail (AActor *spirit);
DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase) DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
{ {
PARAM_ACTION_PROLOGUE;
AActor *spot; AActor *spot;
if ((!self->special2) && (self->health <= (self->SpawnHealth()/2))) 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); P_StartScript (self, NULL, 249, NULL, NULL, 0, 0);
self->special2 = 1; // Don't run again self->special2 = 1; // Don't run again
return; return 0;
} }
if (!self->target) return; if (self->target == NULL)
{
return 0;
}
if (pr_koraxchase()<30) if (pr_koraxchase()<30)
{ {
self->SetState (self->MissileState); 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) DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int i; int i;
// Spawn 6 spirits equalangularly // Spawn 6 spirits equalangularly
for (i = 0; i < 6; ++i) for (i = 0; i < 6; ++i)
{ {
mo = P_SpawnMissileAngle (self, PClass::FindClass("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT); mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT);
if (mo) KSpiritInit (mo, self); if (mo)
{
KSpiritInit (mo, self);
}
} }
P_StartScript (self, NULL, 255, NULL, NULL, 0, 0); // Death script 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) DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
{ {
PARAM_ACTION_PROLOGUE;
if (pr_koraxdecide()<220) if (pr_koraxdecide()<220)
{ {
self->SetState (self->FindState("Attack")); self->SetState (self->FindState("Attack"));
@ -198,6 +212,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
{ {
self->SetState (self->FindState("Command")); self->SetState (self->FindState("Command"));
} }
return 0;
} }
//============================================================================ //============================================================================
@ -208,6 +223,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxDecide)
DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile) DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
{ {
PARAM_ACTION_PROLOGUE;
static const struct { const char *type, *sound; } choices[6] = static const struct { const char *type, *sound; } choices[6] =
{ {
{ "WraithFX1", "WraithMissileFire" }, { "WraithFX1", "WraithMissileFire" },
@ -220,11 +237,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
int type = pr_koraxmissile()%6; int type = pr_koraxmissile()%6;
int i; int i;
const PClass *info; PClassActor *info;
S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM); S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM);
info = PClass::FindClass (choices[type].type); info = PClass::FindActor(choices[type].type);
if (info == NULL) if (info == NULL)
{ {
I_Error ("Unknown Korax missile: %s\n", choices[type].type); I_Error ("Unknown Korax missile: %s\n", choices[type].type);
@ -236,6 +253,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
{ {
KoraxFire (self, info, i); KoraxFire (self, info, i);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -248,6 +266,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand) DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
{ {
PARAM_ACTION_PROLOGUE;
angle_t ang; angle_t ang;
int numcommands; int numcommands;
@ -271,6 +290,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
} }
P_StartScript (self, NULL, 250+(pr_koraxcommand()%numcommands), NULL, NULL, 0, 0); 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] = 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) DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam)
{ {
PARAM_ACTION_PROLOGUE;
if (self->health-- <= 0) if (self->health-- <= 0)
{ {
S_Sound (self, CHAN_VOICE, "SpiritDie", 1, ATTN_NORM); 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_KBolt)
{ {
PARAM_ACTION_PROLOGUE;
// Countdown lifetime // Countdown lifetime
if (self->special1-- <= 0) if (self->special1-- <= 0)
{ {
self->Destroy (); self->Destroy ();
} }
return 0;
} }
//============================================================================ //============================================================================
@ -448,6 +474,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBolt)
DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise) DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
fixed_t z; fixed_t z;
@ -466,6 +494,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
{ {
// Maybe cap it off here // 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 *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; AActor *th;
angle_t an; angle_t an;

View file

@ -51,6 +51,8 @@ int AFrostMissile::DoSpecialDamage (AActor *victim, int damage, FName damagetype
DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
@ -62,14 +64,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AWeapon *weapon = self->player->ReadyWeapon; AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, "MageShardsFire", 1, ATTN_NORM); 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 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) DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int spawndir = self->special1; int spawndir = self->special1;
int spermcount = self->special2; int spermcount = self->special2;
if (spermcount <= 0) return; // No sperm left if (spermcount <= 0)
{
return 0; // No sperm left
}
self->special2 = 0; self->special2 = 0;
spermcount--; spermcount--;
@ -173,4 +181,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
mo->args[0] = (spermcount==3)?2:0; 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) DEFINE_ACTION_FUNCTION(AActor, A_LightningReady)
{ {
PARAM_ACTION_PROLOGUE;
DoReadyWeapon(self); DoReadyWeapon(self);
if (pr_lightningready() < 160) if (pr_lightningready() < 160)
{ {
S_Sound (self, CHAN_WEAPON, "MageLightningReady", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
{ {
PARAM_ACTION_PROLOGUE;
AActor *cMo; AActor *cMo;
AActor *target = NULL; AActor *target = NULL;
int zigZag; int zigZag;
@ -149,7 +154,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
{ {
if (self->lastenemy == NULL) if (self->lastenemy == NULL)
{ {
return; return 0;
} }
self->SetZ(self->floorz); self->SetZ(self->floorz);
target = self->lastenemy->tracer; target = self->lastenemy->tracer;
@ -196,6 +201,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
P_ThrustMobj (self, self->angle, self->Speed>>1); 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) 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; AActor *mo;
fixed_t deltaZ; fixed_t deltaZ;
if (lightning == NULL)
{
lightning = PClass::FindActor(NAME_LightningZap);
}
CALL_ACTION(A_LightningClip, self); CALL_ACTION(A_LightningClip, self);
self->health -= 8; self->health -= 8;
if (self->health <= 0) if (self->health <= 0)
{ {
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
return; return 0;
} }
if (self->flags3 & MF3_FLOORHUGGER) 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); 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
{ {
ACTION_PARAM_START(2); PARAM_ACTION_PROLOGUE;
ACTION_PARAM_CLASS(floor, 0); PARAM_CLASS_OPT(floor, AActor) { floor = PClass::FindActor("LightningFloor"); }
ACTION_PARAM_CLASS(ceiling, 1); PARAM_CLASS_OPT(ceiling, AActor) { ceiling = PClass::FindActor("LightningCeiling"); }
AActor *fmo, *cmo; AActor *fmo, *cmo;
@ -291,6 +304,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
weapon->DepleteAmmo (weapon->bAltFire); weapon->DepleteAmmo (weapon->bAltFire);
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -301,6 +315,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MLightningAttack)
DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic) DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = self->lastenemy; mo = self->lastenemy;
@ -316,6 +332,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
self->vely = mo->vely; self->vely = mo->vely;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -326,17 +343,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
DEFINE_ACTION_FUNCTION(AActor, A_LastZap) 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; AActor *mo;
if (lightning == NULL)
{
lightning = PClass::FindActor(NAME_LightningZap);
}
mo = Spawn(lightning, self->Pos(), ALLOW_REPLACE); mo = Spawn(lightning, self->Pos(), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->SetState (mo->FindState (NAME_Death)); mo->SetState (mo->FindState (NAME_Death));
mo->velz = 40*FRACUNIT; 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) DEFINE_ACTION_FUNCTION(AActor, A_LightningRemove)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
mo = self->lastenemy; mo = self->lastenemy;
@ -355,4 +380,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningRemove)
mo->lastenemy = NULL; mo->lastenemy = NULL;
P_ExplodeMissile (mo, NULL, 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) DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
player_t *player; player_t *player;
AActor *linetarget; AActor *linetarget;
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon); AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon);
if (weapon != NULL) if (weapon != NULL)
{ {
if (!weapon->DepleteAmmo (weapon->bAltFire)) if (!weapon->DepleteAmmo (weapon->bAltFire))
return; return 0;
} }
angle = self->angle; angle = self->angle;
@ -151,6 +153,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
MStaffSpawn (self, angle+ANGLE_1*5); MStaffSpawn (self, angle+ANGLE_1*5);
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
weapon->MStaffCount = 3; weapon->MStaffCount = 3;
return 0;
} }
//============================================================================ //============================================================================
@ -161,6 +164,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette) DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
{ {
PARAM_ACTION_PROLOGUE;
if (self->player != NULL) if (self->player != NULL)
{ {
AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon); AMWeapBloodscourge *weapon = static_cast<AMWeapBloodscourge *> (self->player->ReadyWeapon);
@ -169,6 +174,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
weapon->MStaffCount--; weapon->MStaffCount--;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -179,11 +185,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffPalette)
DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack) DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
{ {
PARAM_ACTION_PROLOGUE;
if ((self->tracer == 0) && (pr_mstafftrack()<50)) if ((self->tracer == 0) && (pr_mstafftrack()<50))
{ {
self->tracer = P_RoughMonsterSearch (self, 10, true); self->tracer = P_RoughMonsterSearch (self, 10, true);
} }
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10); 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) DEFINE_ACTION_FUNCTION(AActor, A_MageAttack)
{ {
if (!self->target) return; PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
{
return 0;
}
angle_t angle; angle_t angle;
angle = self->angle; angle = self->angle;
MStaffSpawn2 (self, angle); MStaffSpawn2 (self, angle);
MStaffSpawn2 (self, angle-ANGLE_1*5); MStaffSpawn2 (self, angle-ANGLE_1*5);
MStaffSpawn2 (self, angle+ANGLE_1*5); MStaffSpawn2 (self, angle+ANGLE_1*5);
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
{ {
PARAM_ACTION_PROLOGUE;
angle_t angle; angle_t angle;
int damage; int damage;
int slope; int slope;
@ -69,7 +71,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
if (NULL == (player = self->player)) if (NULL == (player = self->player))
{ {
return; return 0;
} }
damage = 3+(pr_snoutattack()&3); 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_PigPain)
{ {
PARAM_ACTION_PROLOGUE;
CALL_ACTION(A_Pain, self); CALL_ACTION(A_Pain, self);
if (self->Z() <= self->floorz) if (self->Z() <= self->floorz)
{ {
self->velz = FRACUNIT*7/2; self->velz = FRACUNIT*7/2;
} }
return 0;
} }

View file

@ -25,8 +25,11 @@ static FRandom pr_delaygib ("DelayGib");
DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide) DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE; self->renderflags &= ~RF_INVISIBLE;
self->floorclip = 24*FRACUNIT; self->floorclip = 24*FRACUNIT;
return 0;
} }
//============================================================================ //============================================================================
@ -37,8 +40,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide) DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags |= RF_INVISIBLE; self->renderflags |= RF_INVISIBLE;
self->floorclip = 0; self->floorclip = 0;
return 0;
} }
//============================================================================ //============================================================================
@ -50,7 +56,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump) DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump)
{ {
PARAM_ACTION_PROLOGUE;
self->floorclip -= 4*FRACUNIT; self->floorclip -= 4*FRACUNIT;
return 0;
} }
//============================================================================ //============================================================================
@ -61,7 +70,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump) DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump)
{ {
PARAM_ACTION_PROLOGUE;
self->floorclip += 4*FRACUNIT; self->floorclip += 4*FRACUNIT;
return 0;
} }
//============================================================================ //============================================================================
@ -74,21 +86,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide) DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide)
{ {
PARAM_ACTION_PROLOGUE;
if (self->MissileState != NULL) if (self->MissileState != NULL)
{ {
if (pr_serpenthump() > 30) if (pr_serpenthump() > 30)
{ {
return; return 0;
} }
else if (pr_serpenthump() < 40) else if (pr_serpenthump() < 40)
{ // Missile attack { // Missile attack
self->SetState (self->MeleeState); self->SetState (self->MeleeState);
return; return 0;
} }
} }
else if (pr_serpenthump() > 3) else if (pr_serpenthump() > 3)
{ {
return; return 0;
} }
if (!self->CheckMeleeRange ()) if (!self->CheckMeleeRange ())
{ // The hump shouldn't occur when within melee range { // 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); 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) DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
if (self->MissileState != NULL) if (self->MissileState != NULL)
{ {
if (!self->CheckMeleeRange ()) if (!self->CheckMeleeRange ())
{ {
self->SetState (self->FindState ("Attack")); self->SetState (self->FindState ("Attack"));
return; return 0;
} }
} }
if (P_CheckMeleeRange2 (self)) if (P_CheckMeleeRange2 (self))
@ -139,6 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
self->SetState (self->FindState ("Attack")); self->SetState (self->FindState ("Attack"));
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -149,14 +167,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentCheckForAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentChooseAttack) DEFINE_ACTION_FUNCTION(AActor, A_SerpentChooseAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target || self->CheckMeleeRange()) if (!self->target || self->CheckMeleeRange())
{ {
return; return 0;
} }
if (self->MissileState != NULL) if (self->MissileState != NULL)
{ {
self->SetState (self->MissileState); self->SetState (self->MissileState);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -167,9 +188,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentChooseAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack) DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
if (self->CheckMeleeRange ()) if (self->CheckMeleeRange ())
{ {
@ -182,6 +205,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
{ {
CALL_ACTION(A_SerpentCheckForAttack, self); CALL_ACTION(A_SerpentCheckForAttack, self);
} }
return 0;
} }
//============================================================================ //============================================================================
@ -192,6 +216,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs) DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
static const char *GibTypes[] = static const char *GibTypes[] =
{ {
@ -215,6 +241,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
mo->floorclip = 6*FRACUNIT; mo->floorclip = 6*FRACUNIT;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -225,7 +252,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
DEFINE_ACTION_FUNCTION(AActor, A_FloatGib) DEFINE_ACTION_FUNCTION(AActor, A_FloatGib)
{ {
PARAM_ACTION_PROLOGUE;
self->floorclip -= FRACUNIT; self->floorclip -= FRACUNIT;
return 0;
} }
//============================================================================ //============================================================================
@ -236,7 +266,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatGib)
DEFINE_ACTION_FUNCTION(AActor, A_SinkGib) DEFINE_ACTION_FUNCTION(AActor, A_SinkGib)
{ {
PARAM_ACTION_PROLOGUE;
self->floorclip += FRACUNIT; self->floorclip += FRACUNIT;
return 0;
} }
//============================================================================ //============================================================================
@ -247,7 +280,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SinkGib)
DEFINE_ACTION_FUNCTION(AActor, A_DelayGib) DEFINE_ACTION_FUNCTION(AActor, A_DelayGib)
{ {
PARAM_ACTION_PROLOGUE;
self->tics -= pr_delaygib()>>2; self->tics -= pr_delaygib()>>2;
return 0;
} }
//============================================================================ //============================================================================
@ -258,6 +294,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DelayGib)
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck) DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck)
{ {
PARAM_ACTION_PROLOGUE;
if (self->Z() <= self->floorz) if (self->Z() <= self->floorz)
{ {
if (Terrains[P_GetThingFloorType(self)].IsLiquid) if (Terrains[P_GetThingFloorType(self)].IsLiquid)
@ -270,5 +308,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck)
self->SetState (self->FindState(NAME_Death)); 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) DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp)
{ {
PARAM_ACTION_PROLOGUE;
self->special2 = 5; // Raise speed self->special2 = 5; // Raise speed
self->args[0] = 1; // Mark as up self->args[0] = 1; // Mark as up
self->floorclip = 0; self->floorclip = 0;
self->flags = MF_SOLID; self->flags = MF_SOLID;
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
self->special1 = 0L; self->special1 = 0L;
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn) DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
{ {
PARAM_ACTION_PROLOGUE;
self->special2 = 5; // Raise speed self->special2 = 5; // Raise speed
self->args[0] = 0; // Mark as down self->args[0] = 0; // Mark as down
self->floorclip = self->GetDefault()->height; self->floorclip = self->GetDefault()->height;
@ -96,11 +101,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
self->renderflags = RF_INVISIBLE; self->renderflags = RF_INVISIBLE;
static_cast<AThrustFloor *>(self)->DirtClump = static_cast<AThrustFloor *>(self)->DirtClump =
Spawn("DirtClump", self->Pos(), ALLOW_REPLACE); Spawn("DirtClump", self->Pos(), ALLOW_REPLACE);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise) DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
{ {
PARAM_ACTION_PROLOGUE;
AThrustFloor *actor = static_cast<AThrustFloor *>(self); AThrustFloor *actor = static_cast<AThrustFloor *>(self);
if (A_RaiseMobj (actor, self->special2*FRACUNIT)) if (A_RaiseMobj (actor, self->special2*FRACUNIT))
@ -123,10 +131,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
if (pr_thrustraise()<40) if (pr_thrustraise()<40)
P_SpawnDirt (actor, actor->radius); P_SpawnDirt (actor, actor->radius);
actor->special2++; // Increase raise speed actor->special2++; // Increase raise speed
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower) DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
{ {
PARAM_ACTION_PROLOGUE;
if (A_SinkMobj (self, 6*FRACUNIT)) if (A_SinkMobj (self, 6*FRACUNIT))
{ {
self->args[0] = 0; self->args[0] = 0;
@ -135,10 +146,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
else else
self->SetState (self->FindState ("ThrustInit1"), true); self->SetState (self->FindState ("ThrustInit1"), true);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale) DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
{ {
PARAM_ACTION_PROLOGUE;
AActor *thing; AActor *thing;
FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), self->radius)); FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), self->radius));
while ((thing = it.Next())) while ((thing = it.Next()))
@ -158,5 +172,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
P_TraceBleed (newdam > 0 ? newdam : 10001, thing); P_TraceBleed (newdam > 0 ? newdam : 10001, thing);
self->args[1] = 1; // Mark thrust thing as bloody 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) bool AArtiDarkServant::Use (bool pickup)
{ {
AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindClass ("SummoningDoll")); AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindActor("SummoningDoll"));
if (mo) if (mo)
{ {
mo->target = Owner; mo->target = Owner;
@ -49,6 +49,8 @@ bool AArtiDarkServant::Use (bool pickup)
DEFINE_ACTION_FUNCTION(AActor, A_Summon) DEFINE_ACTION_FUNCTION(AActor, A_Summon)
{ {
PARAM_ACTION_PROLOGUE;
AMinotaurFriend *mo; AMinotaurFriend *mo;
mo = Spawn<AMinotaurFriend> (self->Pos(), ALLOW_REPLACE); mo = Spawn<AMinotaurFriend> (self->Pos(), ALLOW_REPLACE);
@ -59,7 +61,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
mo->Destroy (); mo->Destroy ();
AActor *arti = Spawn<AArtiDarkServant> (self->Pos(), ALLOW_REPLACE); AActor *arti = Spawn<AArtiDarkServant> (self->Pos(), ALLOW_REPLACE);
if (arti) arti->flags |= MF_DROPPED; if (arti) arti->flags |= MF_DROPPED;
return; return 0;
} }
mo->StartTime = level.maptime; mo->StartTime = level.maptime;
@ -79,4 +81,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE); Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE);
S_Sound (self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM); 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) DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnA)
{ {
PARAM_ACTION_PROLOGUE;
TeloSpawn (self, "TelOtherFX2"); TeloSpawn (self, "TelOtherFX2");
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnB) DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnB)
{ {
PARAM_ACTION_PROLOGUE;
TeloSpawn (self, "TelOtherFX3"); TeloSpawn (self, "TelOtherFX3");
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnC) DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnC)
{ {
PARAM_ACTION_PROLOGUE;
TeloSpawn (self, "TelOtherFX4"); TeloSpawn (self, "TelOtherFX4");
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnD) DEFINE_ACTION_FUNCTION(AActor, A_TeloSpawnD)
{ {
PARAM_ACTION_PROLOGUE;
TeloSpawn (self, "TelOtherFX5"); TeloSpawn (self, "TelOtherFX5");
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_CheckTeleRing) DEFINE_ACTION_FUNCTION(AActor, A_CheckTeleRing)
{ {
PARAM_ACTION_PROLOGUE;
if (self->special1-- <= 0) if (self->special1-- <= 0)
{ {
self->SetState (self->FindState(NAME_Death)); 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) DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
{ {
PARAM_ACTION_PROLOGUE;
self->AddZ(48<<FRACBITS); self->AddZ(48<<FRACBITS);
// [RH] Make sure the wraith didn't go into the ceiling // [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 self->special1 = 0; // index into floatbob
return 0;
} }
//============================================================================ //============================================================================
@ -48,11 +51,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit) DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE; self->renderflags &= ~RF_INVISIBLE;
self->flags2 &= ~MF2_NONSHOOTABLE; self->flags2 &= ~MF2_NONSHOOTABLE;
self->flags3 &= ~MF3_DONTBLAST; self->flags3 &= ~MF3_DONTBLAST;
self->flags |= MF_SHOOTABLE|MF_SOLID; self->flags |= MF_SHOOTABLE|MF_SOLID;
self->floorclip = self->height; self->floorclip = self->height;
return 0;
} }
//============================================================================ //============================================================================
@ -63,6 +69,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit)
DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise) DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
{ {
PARAM_ACTION_PROLOGUE;
if (A_RaiseMobj (self, 2*FRACUNIT)) if (A_RaiseMobj (self, 2*FRACUNIT))
{ {
// Reached it's target height // Reached it's target height
@ -75,6 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
} }
P_SpawnDirt (self, self->radius); P_SpawnDirt (self, self->radius);
return 0;
} }
//============================================================================ //============================================================================
@ -85,6 +94,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee) DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee)
{ {
PARAM_ACTION_PROLOGUE;
int amount; int amount;
// Steal health from target and give to self // 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); P_DamageMobj (self->target, self, self, amount, NAME_Melee);
self->health += amount; self->health += amount;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -104,6 +116,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithMelee)
DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
angle_t angle; angle_t angle;
int i; int i;
@ -130,6 +144,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
mo->floorclip = 10*FRACUNIT; mo->floorclip = 10*FRACUNIT;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -142,6 +157,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3) DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int numdropped = pr_wraithfx3()%15; int numdropped = pr_wraithfx3()%15;
@ -159,6 +176,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
mo->target = self; mo->target = self;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -234,6 +252,8 @@ void A_WraithFX4 (AActor *self)
DEFINE_ACTION_FUNCTION(AActor, A_WraithChase) DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
{ {
PARAM_ACTION_PROLOGUE;
int weaveindex = self->special1; int weaveindex = self->special1;
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8);
self->special1 = (weaveindex + 2) & 63; self->special1 = (weaveindex + 2) & 63;
@ -242,6 +262,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
// P_SetMobjState(self, S_WRAITH_RAISE2); // P_SetMobjState(self, S_WRAITH_RAISE2);
// return; // return;
// } // }
A_Chase (self); A_Chase (stack, self);
A_WraithFX4 (self); A_WraithFX4 (self);
return 0;
} }

View file

@ -45,9 +45,7 @@ struct cluster_info_t;
class FScanner; class FScanner;
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma data_seg(".yreg$u") #pragma section(".yreg$u",read)
#pragma data_seg()
#define MSVC_YSEG __declspec(allocate(".yreg$u")) #define MSVC_YSEG __declspec(allocate(".yreg$u"))
#define GCC_YSEG #define GCC_YSEG
#else #else

View file

@ -371,12 +371,12 @@ level_info_t *level_info_t::CheckLevelRedirect ()
{ {
if (RedirectType != NAME_None) if (RedirectType != NAME_None)
{ {
const PClass *type = PClass::FindClass(RedirectType); PClassActor *type = PClass::FindActor(RedirectType);
if (type != NULL) if (type != NULL)
{ {
for (int i = 0; i < MAXPLAYERS; ++i) 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. // check for actual presence of the map.
if (P_CheckMapData(RedirectMapName)) if (P_CheckMapData(RedirectMapName))

View file

@ -68,7 +68,7 @@ bool AArtiTeleport::Use (bool pickup)
bool P_AutoUseChaosDevice (player_t *player) 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) if (arti != NULL)
{ {

View file

@ -105,7 +105,7 @@ void AMinotaurFriend::Die (AActor *source, AActor *inflictor, int dmgflags)
if (mo == NULL) if (mo == NULL)
{ {
AInventory *power = tracer->FindInventory (PClass::FindClass("PowerMinotaur")); AInventory *power = tracer->FindInventory(PClass::FindActor("PowerMinotaur"));
if (power != NULL) if (power != NULL)
{ {
power->Destroy (); power->Destroy ();
@ -132,18 +132,23 @@ bool AMinotaurFriend::OkayToSwitchTarget (AActor *other)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDeath) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDeath)
{ {
PARAM_ACTION_PROLOGUE;
if (Wads.CheckNumForName ("MNTRF1", ns_sprites) < 0 && if (Wads.CheckNumForName ("MNTRF1", ns_sprites) < 0 &&
Wads.CheckNumForName ("MNTRF0", ns_sprites) < 0) Wads.CheckNumForName ("MNTRF0", ns_sprites) < 0)
self->SetState(self->FindState ("FadeOut")); self->SetState(self->FindState ("FadeOut"));
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
{ {
PARAM_ACTION_PROLOGUE;
player_t *player; player_t *player;
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, "minotaur/melee", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "minotaur/melee", 1, ATTN_NORM);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -157,6 +162,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
player->deltaviewheight = -16*FRACUNIT; player->deltaviewheight = -16*FRACUNIT;
} }
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -171,6 +177,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
{ {
PARAM_ACTION_PROLOGUE;
bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);
angle_t angle; angle_t angle;
AActor *target; AActor *target;
@ -179,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
target = self->target; target = self->target;
if (!target) if (!target)
{ {
return; return 0;
} }
if (!friendly) if (!friendly)
{ {
@ -218,6 +226,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
// Don't need to call P_SetMobjState because the current state // Don't need to call P_SetMobjState because the current state
// falls through to the swing attack // falls through to the swing attack
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -228,21 +237,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge)
{ {
PARAM_ACTION_PROLOGUE;
AActor *puff; AActor *puff;
if (!self->target) return; if (self->target == NULL)
{
return 0;
}
if (self->special1 > 0) if (self->special1 > 0)
{ {
const PClass *type; PClassActor *type;
if (gameinfo.gametype == GAME_Heretic) if (gameinfo.gametype == GAME_Heretic)
{ {
type = PClass::FindClass ("PhoenixPuff"); type = PClass::FindActor("PhoenixPuff");
} }
else else
{ {
type = PClass::FindClass ("PunchPuff"); type = PClass::FindActor("PunchPuff");
} }
puff = Spawn (type, self->Pos(), ALLOW_REPLACE); puff = Spawn (type, self->Pos(), ALLOW_REPLACE);
puff->velz = 2*FRACUNIT; puff->velz = 2*FRACUNIT;
@ -254,6 +267,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge)
self->flags2 &= ~MF2_INVULNERABLE; self->flags2 &= ~MF2_INVULNERABLE;
self->SetState (self->SeeState); self->SetState (self->SeeState);
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -266,15 +280,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
angle_t angle; angle_t angle;
fixed_t velz; fixed_t velz;
fixed_t z; fixed_t z;
bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);
if (!self->target) if (self->target == NULL)
{ {
return; return 0;
} }
S_Sound (self, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -283,10 +299,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
damage = pr_atk.HitDice (friendly ? 3 : 5); damage = pr_atk.HitDice (friendly ? 3 : 5);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return; return 0;
} }
z = self->Z() + 40*FRACUNIT; z = self->Z() + 40*FRACUNIT;
const PClass *fx = PClass::FindClass("MinotaurFX1"); PClassActor *fx = PClass::FindActor("MinotaurFX1");
if (fx) if (fx)
{ {
mo = P_SpawnMissileZ (self, z, self->target, fx); mo = P_SpawnMissileZ (self, z, self->target, fx);
@ -301,6 +317,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/16), velz); P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/16), velz);
} }
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -313,13 +330,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
player_t *player; player_t *player;
bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);
if (!self->target) if (!self->target)
{ {
return; return 0;
} }
S_Sound (self, CHAN_VOICE, "minotaur/attack3", 1, ATTN_NORM); S_Sound (self, CHAN_VOICE, "minotaur/attack3", 1, ATTN_NORM);
if (self->CheckMeleeRange()) if (self->CheckMeleeRange())
@ -344,7 +363,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
} }
else else
{ {
mo = P_SpawnMissile (self, self->target, PClass::FindClass("MinotaurFX2")); mo = P_SpawnMissile (self, self->target, PClass::FindActor("MinotaurFX2"));
if (mo != NULL) if (mo != NULL)
{ {
S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM); S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM);
@ -356,6 +375,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
self->SetState (self->FindState ("HammerLoop")); self->SetState (self->FindState ("HammerLoop"));
self->special2 = 1; self->special2 = 1;
} }
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -366,6 +386,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire)
{ {
PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
self->SetZ(self->floorz); self->SetZ(self->floorz);
@ -376,6 +398,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire)
mo->target = self->target; mo->target = self->target;
mo->velx = 1; // Force block checking mo->velx = 1; // Force block checking
P_CheckMissileSpawn (mo, self->radius); P_CheckMissileSpawn (mo, self->radius);
return 0;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -422,6 +445,8 @@ void P_MinotaurSlam (AActor *source, AActor *target)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
{ {
PARAM_ACTION_PROLOGUE;
// In case pain caused him to skip his fade in. // In case pain caused him to skip his fade in.
self->RenderStyle = STYLE_Normal; self->RenderStyle = STYLE_Normal;
@ -432,7 +457,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
if (self1->StartTime >= 0 && (level.maptime - self1->StartTime) >= MAULATORTICS) if (self1->StartTime >= 0 && (level.maptime - self1->StartTime) >= MAULATORTICS)
{ {
P_DamageMobj (self1, NULL, NULL, TELEFRAG_DAMAGE, NAME_None); P_DamageMobj (self1, NULL, NULL, TELEFRAG_DAMAGE, NAME_None);
return; return 0;
} }
} }
@ -454,6 +479,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
self->movedir = (self->movedir + 7) % 8; self->movedir = (self->movedir + 7) % 8;
FaceMovementDirection (self); FaceMovementDirection (self);
} }
return 0;
} }
@ -467,10 +493,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->IsKindOf(RUNTIME_CLASS(AMinotaurFriend))) if (!self->IsKindOf(RUNTIME_CLASS(AMinotaurFriend)))
{ {
CALL_ACTION(A_Look, self); CALL_ACTION(A_Look, self);
return; return 0;
} }
AActor *mo = NULL; AActor *mo = NULL;
@ -531,14 +559,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
{ {
self->SetState (self->FindState ("Roam"), true); self->SetState (self->FindState ("Roam"), true);
} }
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase)
{ {
PARAM_ACTION_PROLOGUE;
if (!self->IsKindOf(RUNTIME_CLASS(AMinotaurFriend))) if (!self->IsKindOf(RUNTIME_CLASS(AMinotaurFriend)))
{ {
A_Chase (self); A_Chase (stack, self);
return; return 0;
} }
AMinotaurFriend *self1 = static_cast<AMinotaurFriend *> (self); AMinotaurFriend *self1 = static_cast<AMinotaurFriend *> (self);
@ -549,7 +580,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase)
if (self1->StartTime >= 0 && (level.maptime - self1->StartTime) >= MAULATORTICS) if (self1->StartTime >= 0 && (level.maptime - self1->StartTime) >= MAULATORTICS)
{ {
P_DamageMobj (self1, NULL, NULL, TELEFRAG_DAMAGE, NAME_None); P_DamageMobj (self1, NULL, NULL, TELEFRAG_DAMAGE, NAME_None);
return; return 0;
} }
if (pr_minotaurchase() < 30) if (pr_minotaurchase() < 30)
@ -559,7 +590,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase)
!(self1->target->flags&MF_SHOOTABLE)) !(self1->target->flags&MF_SHOOTABLE))
{ // look for a new target { // look for a new target
self1->SetIdle(); self1->SetIdle();
return; return 0;
} }
FaceMovementDirection (self1); FaceMovementDirection (self1);
@ -573,14 +604,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase)
S_Sound (self1, CHAN_WEAPON, self1->AttackSound, 1, ATTN_NORM); S_Sound (self1, CHAN_WEAPON, self1->AttackSound, 1, ATTN_NORM);
} }
self1->SetState (self1->MeleeState); self1->SetState (self1->MeleeState);
return; return 0;
} }
// Missile attack // Missile attack
if (self1->MissileState && P_CheckMissileRange(self1)) if (self1->MissileState && P_CheckMissileRange(self1))
{ {
self1->SetState (self1->MissileState); self1->SetState (self1->MissileState);
return; return 0;
} }
// chase towards target // chase towards target
@ -595,5 +626,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase)
{ {
self1->PlayActiveSound (); self1->PlayActiveSound ();
} }
return 0;
} }

View file

@ -82,7 +82,7 @@ void A_Unblock(AActor *self, bool drop)
// If the actor has attached metadata for items to drop, drop those. // If the actor has attached metadata for items to drop, drop those.
if (drop && !self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB] if (drop && !self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB]
{ {
FDropItem *di = self->GetDropItems(); DDropItem *di = self->GetDropItems();
if (di != NULL) if (di != NULL)
{ {
@ -90,8 +90,11 @@ void A_Unblock(AActor *self, bool drop)
{ {
if (di->Name != NAME_None) if (di->Name != NAME_None)
{ {
const PClass *ti = PClass::FindClass(di->Name); PClassActor *ti = PClass::FindActor(di->Name);
if (ti) P_DropItem (self, ti, di->amount, di->probability); if (ti != NULL)
{
P_DropItem (self, ti, di->Amount, di->Probability);
}
} }
di = di->Next; di = di->Next;
} }
@ -101,12 +104,16 @@ void A_Unblock(AActor *self, bool drop)
DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
{ {
PARAM_ACTION_PROLOGUE;
A_Unblock(self, true); A_Unblock(self, true);
return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_Fall) DEFINE_ACTION_FUNCTION(AActor, A_Fall)
{ {
PARAM_ACTION_PROLOGUE;
A_Unblock(self, true); A_Unblock(self, true);
return 0;
} }
//========================================================================== //==========================================================================
@ -117,8 +124,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Fall)
DEFINE_ACTION_FUNCTION(AActor, A_SetFloorClip) DEFINE_ACTION_FUNCTION(AActor, A_SetFloorClip)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 |= MF2_FLOORCLIP; self->flags2 |= MF2_FLOORCLIP;
self->AdjustFloorClip (); self->AdjustFloorClip ();
return 0;
} }
//========================================================================== //==========================================================================
@ -129,8 +139,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetFloorClip)
DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip) DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~MF2_FLOORCLIP; self->flags2 &= ~MF2_FLOORCLIP;
self->floorclip = 0; self->floorclip = 0;
return 0;
} }
//========================================================================== //==========================================================================
@ -141,7 +154,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip)
DEFINE_ACTION_FUNCTION(AActor, A_HideThing) DEFINE_ACTION_FUNCTION(AActor, A_HideThing)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags |= RF_INVISIBLE; self->renderflags |= RF_INVISIBLE;
return 0;
} }
//========================================================================== //==========================================================================
@ -152,7 +168,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideThing)
DEFINE_ACTION_FUNCTION(AActor, A_UnHideThing) DEFINE_ACTION_FUNCTION(AActor, A_UnHideThing)
{ {
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE; self->renderflags &= ~RF_INVISIBLE;
return 0;
} }
//============================================================================ //============================================================================
@ -163,6 +182,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnHideThing)
DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath) DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
{ {
PARAM_ACTION_PROLOGUE;
int t = pr_freezedeath(); int t = pr_freezedeath();
self->tics = 75+t+pr_freezedeath(); self->tics = 75+t+pr_freezedeath();
self->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_ICECORPSE; self->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_ICECORPSE;
@ -196,6 +217,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
self->args[1], self->args[2], self->args[3], self->args[4]); self->args[1], self->args[2], self->args[3], self->args[4]);
self->special = 0; self->special = 0;
} }
return 0;
} }
//========================================================================== //==========================================================================
@ -206,8 +228,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
DEFINE_ACTION_FUNCTION(AActor, A_GenericFreezeDeath) DEFINE_ACTION_FUNCTION(AActor, A_GenericFreezeDeath)
{ {
PARAM_ACTION_PROLOGUE;
self->Translation = TRANSLATION(TRANSLATION_Standard, 7); self->Translation = TRANSLATION(TRANSLATION_Standard, 7);
CALL_ACTION(A_FreezeDeath, self); CALL_ACTION(A_FreezeDeath, self);
return 0;
} }
//============================================================================ //============================================================================
@ -218,6 +243,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenericFreezeDeath)
DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics) DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics)
{ {
PARAM_ACTION_PROLOGUE;
int floor; int floor;
self->tics = 70+(pr_icesettics()&63); self->tics = 70+(pr_icesettics()&63);
@ -230,6 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics)
{ {
self->tics <<= 1; self->tics <<= 1;
} }
return 0;
} }
//============================================================================ //============================================================================
@ -240,6 +268,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics)
DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
{ {
PARAM_ACTION_PROLOGUE;
int i; int i;
int numChunks; int numChunks;
@ -248,7 +277,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
if ((self->velx || self->vely || self->velz) && !(self->flags6 & MF6_SHATTERING)) if ((self->velx || self->vely || self->velz) && !(self->flags6 & MF6_SHATTERING))
{ {
self->tics = 3*TICRATE; self->tics = 3*TICRATE;
return; return 0;
} }
self->velx = self->vely = self->velz = 0; self->velx = self->vely = self->velz = 0;
S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM);
@ -312,6 +341,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
A_Unblock(self, true); A_Unblock(self, true);
self->SetState(self->FindState(NAME_Null)); self->SetState(self->FindState(NAME_Null));
return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -413,13 +443,20 @@ void DCorpsePointer::Serialize (FArchive &arc)
// throw another corpse on the queue // throw another corpse on the queue
DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse) DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse)
{ {
PARAM_ACTION_PROLOGUE;
if (sv_corpsequeuesize > 0) if (sv_corpsequeuesize > 0)
{
new DCorpsePointer (self); new DCorpsePointer (self);
}
return 0;
} }
// Remove an self from the queue (for resurrection) // Remove an self from the queue (for resurrection)
DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse) DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse)
{ {
PARAM_ACTION_PROLOGUE;
TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER); TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER);
DCorpsePointer *corpsePtr; DCorpsePointer *corpsePtr;
@ -429,9 +466,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse)
{ {
corpsePtr->Corpse = NULL; corpsePtr->Corpse = NULL;
corpsePtr->Destroy (); corpsePtr->Destroy ();
return; return 0;
} }
} }
return 0;
} }
//============================================================================ //============================================================================
@ -442,7 +480,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse)
DEFINE_ACTION_FUNCTION(AActor, A_SetInvulnerable) DEFINE_ACTION_FUNCTION(AActor, A_SetInvulnerable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 |= MF2_INVULNERABLE; self->flags2 |= MF2_INVULNERABLE;
return 0;
} }
//============================================================================ //============================================================================
@ -453,7 +494,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetInvulnerable)
DEFINE_ACTION_FUNCTION(AActor, A_UnSetInvulnerable) DEFINE_ACTION_FUNCTION(AActor, A_UnSetInvulnerable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~MF2_INVULNERABLE; self->flags2 &= ~MF2_INVULNERABLE;
return 0;
} }
//============================================================================ //============================================================================
@ -464,7 +508,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetInvulnerable)
DEFINE_ACTION_FUNCTION(AActor, A_SetReflective) DEFINE_ACTION_FUNCTION(AActor, A_SetReflective)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 |= MF2_REFLECTIVE; self->flags2 |= MF2_REFLECTIVE;
return 0;
} }
//============================================================================ //============================================================================
@ -475,7 +522,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetReflective)
DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflective) DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflective)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~MF2_REFLECTIVE; self->flags2 &= ~MF2_REFLECTIVE;
return 0;
} }
//============================================================================ //============================================================================
@ -486,7 +536,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflective)
DEFINE_ACTION_FUNCTION(AActor, A_SetReflectiveInvulnerable) DEFINE_ACTION_FUNCTION(AActor, A_SetReflectiveInvulnerable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; self->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE;
return 0;
} }
//============================================================================ //============================================================================
@ -497,7 +550,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetReflectiveInvulnerable)
DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflectiveInvulnerable) DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflectiveInvulnerable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~(MF2_REFLECTIVE|MF2_INVULNERABLE); self->flags2 &= ~(MF2_REFLECTIVE|MF2_INVULNERABLE);
return 0;
} }
//========================================================================== //==========================================================================
@ -508,8 +564,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflectiveInvulnerable)
DEFINE_ACTION_FUNCTION(AActor, A_SetShootable) DEFINE_ACTION_FUNCTION(AActor, A_SetShootable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~MF2_NONSHOOTABLE; self->flags2 &= ~MF2_NONSHOOTABLE;
self->flags |= MF_SHOOTABLE; self->flags |= MF_SHOOTABLE;
return 0;
} }
//========================================================================== //==========================================================================
@ -520,8 +579,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetShootable)
DEFINE_ACTION_FUNCTION(AActor, A_UnSetShootable) DEFINE_ACTION_FUNCTION(AActor, A_UnSetShootable)
{ {
PARAM_ACTION_PROLOGUE;
self->flags2 |= MF2_NONSHOOTABLE; self->flags2 |= MF2_NONSHOOTABLE;
self->flags &= ~MF_SHOOTABLE; self->flags &= ~MF_SHOOTABLE;
return 0;
} }
//=========================================================================== //===========================================================================
@ -532,7 +594,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetShootable)
DEFINE_ACTION_FUNCTION(AActor, A_NoGravity) DEFINE_ACTION_FUNCTION(AActor, A_NoGravity)
{ {
PARAM_ACTION_PROLOGUE;
self->flags |= MF_NOGRAVITY; self->flags |= MF_NOGRAVITY;
return 0;
} }
//=========================================================================== //===========================================================================
@ -543,8 +608,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoGravity)
DEFINE_ACTION_FUNCTION(AActor, A_Gravity) DEFINE_ACTION_FUNCTION(AActor, A_Gravity)
{ {
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_NOGRAVITY; self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT; self->gravity = FRACUNIT;
return 0;
} }
//=========================================================================== //===========================================================================
@ -555,8 +623,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Gravity)
DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) DEFINE_ACTION_FUNCTION(AActor, A_LowGravity)
{ {
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_NOGRAVITY; self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT/8; self->gravity = FRACUNIT/8;
return 0;
} }
//=========================================================================== //===========================================================================

View file

@ -180,7 +180,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
// The differences include not using a default value, and of course the way // The differences include not using a default value, and of course the way
// the damage factor info is obtained. // the damage factor info is obtained.
const fixed_t *pdf = NULL; const fixed_t *pdf = NULL;
DmgFactors *df = PClass::FindClass(ArmorType)->ActorInfo->DamageFactors; DmgFactors *df = PClass::FindActor(ArmorType)->DamageFactors;
if (df != NULL && df->CountUsed() != 0) if (df != NULL && df->CountUsed() != 0)
{ {
pdf = df->CheckFactor(damageType); pdf = df->CheckFactor(damageType);

View file

@ -369,9 +369,9 @@ void APowerInvulnerable::InitEffect ()
Super::InitEffect(); Super::InitEffect();
Owner->effects &= ~FX_RESPAWNINVUL; Owner->effects &= ~FX_RESPAWNINVUL;
Owner->flags2 |= MF2_INVULNERABLE; Owner->flags2 |= MF2_INVULNERABLE;
if (Mode == NAME_None) if (Mode == NAME_None && Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
{ {
Mode = (ENamedName)RUNTIME_TYPE(Owner)->Meta.GetMetaInt(APMETA_InvulMode); Mode = static_cast<PClassPlayerPawn *>(Owner->GetClass())->InvulMode;
} }
if (Mode == NAME_Reflective) if (Mode == NAME_Reflective)
{ {
@ -1619,8 +1619,8 @@ void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bo
static const fixed_t def = 4*FRACUNIT; static const fixed_t def = 4*FRACUNIT;
if (!passive && damage > 0) if (!passive && damage > 0)
{ {
const fixed_t * pdf = NULL; const fixed_t *pdf = NULL;
DmgFactors * df = GetClass()->ActorInfo->DamageFactors; DmgFactors *df = GetClass()->DamageFactors;
if (df != NULL && df->CountUsed() != 0) if (df != NULL && df->CountUsed() != 0)
{ {
pdf = df->CheckFactor(damageType); pdf = df->CheckFactor(damageType);
@ -1700,7 +1700,7 @@ void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage
if (passive && damage > 0) if (passive && damage > 0)
{ {
const fixed_t *pdf = NULL; const fixed_t *pdf = NULL;
DmgFactors *df = GetClass()->ActorInfo->DamageFactors; DmgFactors *df = GetClass()->DamageFactors;
if (df != NULL && df->CountUsed() != 0) if (df != NULL && df->CountUsed() != 0)
{ {
pdf = df->CheckFactor(damageType); pdf = df->CheckFactor(damageType);
@ -1887,9 +1887,9 @@ void APowerMorph::InitEffect( )
if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None) if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None)
{ {
player_t *realplayer = Owner->player; // Remember the identity of the player player_t *realplayer = Owner->player; // Remember the identity of the player
const PClass *morph_flash = PClass::FindClass (MorphFlash); PClassActor *morph_flash = PClass::FindActor(MorphFlash);
const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); PClassActor *unmorph_flash = PClass::FindActor(UnMorphFlash);
const PClass *player_class = PClass::FindClass (PlayerClass); PClassPlayerPawn *player_class = dyn_cast<PClassPlayerPawn>(PClass::FindClass (PlayerClass));
if (P_MorphPlayer(realplayer, realplayer, player_class, -1/*INDEFINITELY*/, MorphStyle, morph_flash, unmorph_flash)) if (P_MorphPlayer(realplayer, realplayer, player_class, -1/*INDEFINITELY*/, MorphStyle, morph_flash, unmorph_flash))
{ {
Owner = realplayer->mo; // Replace the new owner in our owner; safe because we are not attached to anything yet Owner = realplayer->mo; // Replace the new owner in our owner; safe because we are not attached to anything yet

View file

@ -44,7 +44,7 @@ public:
virtual bool Use (bool pickup); virtual bool Use (bool pickup);
virtual void Serialize (FArchive &arc); virtual void Serialize (FArchive &arc);
const PClass *PowerupType; PClassActor *PowerupType;
int EffectTics; // Non-0 to override the powerup's default tics int EffectTics; // Non-0 to override the powerup's default tics
PalEntry BlendColor; // Non-0 to override the powerup's default blend PalEntry BlendColor; // Non-0 to override the powerup's default blend
FNameNoInit Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility FNameNoInit Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility

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