gzdoom/src/scripting/vmthunks_actors.cpp
2022-11-24 23:52:52 +01:00

2092 lines
54 KiB
C++

//-----------------------------------------------------------------------------
//
// Copyright 2016-2018 Christoph Oelckers
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//-----------------------------------------------------------------------------
//
// VM thunks for internal functions of actor classes
//
// Important note about this file: Since everything in here is supposed to be called
// from JIT-compiled VM code it needs to be very careful about calling conventions.
// As a result none of the integer sized struct types may be used as function
// arguments, because current C++ calling conventions require them to be passed
// by reference. The JIT code, however will pass them by value so any direct native function
// taking such an argument needs to receive it as a naked int.
//
//-----------------------------------------------------------------------------
#include "vm.h"
#include "r_defs.h"
#include "g_levellocals.h"
#include "s_sound.h"
#include "p_local.h"
#include "v_font.h"
#include "gstrings.h"
#include "a_keys.h"
#include "sbar.h"
#include "doomstat.h"
#include "p_acs.h"
#include "a_pickups.h"
#include "a_specialspot.h"
#include "actorptrselect.h"
#include "a_weapons.h"
#include "d_player.h"
#include "p_setup.h"
#include "i_music.h"
#include "p_terrain.h"
#include "p_checkposition.h"
#include "p_linetracedata.h"
#include "p_local.h"
#include "p_effect.h"
#include "p_spec.h"
#include "actorinlines.h"
#include "p_enemy.h"
#include "gi.h"
DVector2 AM_GetPosition();
int Net_GetLatency(int *ld, int *ad);
void PrintPickupMessage(bool localview, const FString &str);
bool P_CheckForResurrection(AActor* self, bool usevilestates, FState* state = nullptr, FSoundID sound = 0);
// FCheckPosition requires explicit construction and destruction when used in the VM
static void FCheckPosition_C(void *mem)
{
new(mem) FCheckPosition;
}
DEFINE_ACTION_FUNCTION_NATIVE(_FCheckPosition, _Constructor, FCheckPosition_C)
{
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
FCheckPosition_C(self);
return 0;
}
static void FCheckPosition_D(FCheckPosition *self)
{
self->~FCheckPosition();
}
DEFINE_ACTION_FUNCTION_NATIVE(_FCheckPosition, _Destructor, FCheckPosition_D)
{
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
self->~FCheckPosition();
return 0;
}
static void ClearLastRipped(FCheckPosition *self)
{
self->LastRipped.Clear();
}
DEFINE_ACTION_FUNCTION_NATIVE(_FCheckPosition, ClearLastRipped, ClearLastRipped)
{
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
self->LastRipped.Clear();
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(DObject, SetMusicVolume, I_SetMusicVolume)
{
PARAM_PROLOGUE;
PARAM_FLOAT(vol);
I_SetMusicVolume(vol);
return 0;
}
//=====================================================================================
//
// AActor exports (this will be expanded)
//
//=====================================================================================
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetPointer, COPY_AAPTR)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(ptr);
ACTION_RETURN_OBJECT(COPY_AAPTR(self, ptr));
}
//==========================================================================
//
// Custom sound functions.
//
//==========================================================================
static void NativeStopSound(AActor *actor, int slot)
{
S_StopSound(actor, slot);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_StopSound, NativeStopSound)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(slot);
S_StopSound(self, slot);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_StopSounds, S_StopActorSounds)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(chanmin);
PARAM_INT(chanmax);
S_StopActorSounds(self, chanmin, chanmax);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SoundPitch, S_ChangeActorSoundPitch)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(channel);
PARAM_FLOAT(pitch);
S_ChangeActorSoundPitch(self, channel, pitch);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SoundVolume, S_ChangeActorSoundVolume)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(channel);
PARAM_FLOAT(volume);
S_ChangeActorSoundVolume(self, channel, volume);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_PlaySound, A_PlaySound)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_SOUND(soundid);
PARAM_INT(channel);
PARAM_FLOAT(volume);
PARAM_BOOL(looping);
PARAM_FLOAT(attenuation);
PARAM_BOOL(local);
PARAM_FLOAT(pitch);
A_PlaySound(self, soundid, channel, volume, looping, attenuation, local, pitch);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_StartSound, A_StartSound)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_SOUND(soundid);
PARAM_INT(channel);
PARAM_INT(flags);
PARAM_FLOAT(volume);
PARAM_FLOAT(attenuation);
PARAM_FLOAT(pitch);
PARAM_FLOAT(startTime);
A_StartSound(self, soundid, channel, flags, volume, attenuation, pitch, startTime);
return 0;
}
void A_StartSoundIfNotSame(AActor *self, int soundid, int checksoundid, int channel, int flags, double volume, double attenuation, double pitch, double startTime)
{
if (!S_AreSoundsEquivalent (self, soundid, checksoundid))
A_StartSound(self, soundid, channel, flags, volume, attenuation, pitch, startTime);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_StartSoundIfNotSame, A_StartSoundIfNotSame)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(soundid);
PARAM_INT(checksoundid);
PARAM_INT(channel);
PARAM_INT(flags);
PARAM_FLOAT(volume);
PARAM_FLOAT(attenuation);
PARAM_FLOAT(pitch);
PARAM_FLOAT(startTime);
A_StartSoundIfNotSame(self, soundid, checksoundid, channel, flags, volume, attenuation, pitch, startTime);
return 0;
}
// direct native scripting export.
static int S_IsActorPlayingSomethingID(AActor* actor, int channel, int sound_id)
{
return S_IsActorPlayingSomething(actor, channel, FSoundID::fromInt(sound_id));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, IsActorPlayingSound, S_IsActorPlayingSomethingID)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(channel);
PARAM_SOUND(soundid);
ACTION_RETURN_BOOL(S_IsActorPlayingSomething(self, channel, soundid));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckKeys, P_CheckKeys)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(locknum);
PARAM_BOOL(remote);
PARAM_BOOL(quiet);
ACTION_RETURN_BOOL(P_CheckKeys(self, locknum, remote, quiet));
}
static double deltaangleDbl(double a1, double a2)
{
return deltaangle(DAngle::fromDeg(a1), DAngle::fromDeg(a2)).Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, deltaangle, deltaangleDbl) // should this be global?
{
PARAM_PROLOGUE;
PARAM_FLOAT(a1);
PARAM_FLOAT(a2);
ACTION_RETURN_FLOAT(deltaangle(DAngle::fromDeg(a1), DAngle::fromDeg(a2)).Degrees());
}
static double absangleDbl(double a1, double a2)
{
return absangle(DAngle::fromDeg(a1), DAngle::fromDeg(a2)).Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, absangle, absangleDbl) // should this be global?
{
PARAM_PROLOGUE;
PARAM_FLOAT(a1);
PARAM_FLOAT(a2);
ACTION_RETURN_FLOAT(absangle(DAngle::fromDeg(a1), DAngle::fromDeg(a2)).Degrees());
}
static double Distance2DSquared(AActor *self, AActor *other)
{
return self->Distance2DSquared(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Distance2DSquared, Distance2DSquared)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_FLOAT(self->Distance2DSquared(other));
}
static double Distance3DSquared(AActor *self, AActor *other)
{
return self->Distance3DSquared(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Distance3DSquared, Distance3DSquared)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_FLOAT(self->Distance3DSquared(other));
}
static double Distance2D(AActor *self, AActor *other)
{
return self->Distance2D(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Distance2D, Distance2D)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_FLOAT(self->Distance2D(other));
}
static double Distance3D(AActor *self, AActor *other)
{
return self->Distance3D(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Distance3D, Distance3D)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_FLOAT(self->Distance3D(other));
}
static void AddZ(AActor *self, double addz, bool moving)
{
self->AddZ(addz, moving);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, AddZ, AddZ)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(addz);
PARAM_BOOL(moving);
self->AddZ(addz, moving);
return 0;
}
static void SetZ(AActor *self, double z)
{
self->SetZ(z);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetZ, SetZ)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(z);
self->SetZ(z);
return 0;
}
static void SetDamage(AActor *self, int dmg)
{
self->SetDamage(dmg);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetDamage, SetDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(dmg);
self->SetDamage(dmg);
return 0;
}
static double PitchFromVel(AActor* self)
{
return self->Vel.Pitch().Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, PitchFromVel, PitchFromVel)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_FLOAT(PitchFromVel(self));
}
// This combines all 3 variations of the internal function
static void VelFromAngle(AActor *self, double speed, double angle)
{
if (speed == 1e37)
{
self->VelFromAngle();
}
else
{
if (angle == 1e37)
{
self->VelFromAngle(speed);
}
else
{
self->VelFromAngle(speed, DAngle::fromDeg(angle));
}
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, VelFromAngle, VelFromAngle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(speed);
PARAM_FLOAT(angle);
VelFromAngle(self, speed, angle);
return 0;
}
static void Vel3DFromAngle(AActor *self, double speed, double angle, double pitch)
{
self->Vel3DFromAngle(DAngle::fromDeg(angle), DAngle::fromDeg(pitch), speed);
}
// This combines all 3 variations of the internal function
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vel3DFromAngle, Vel3DFromAngle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(speed);
PARAM_ANGLE(angle);
PARAM_ANGLE(pitch);
self->Vel3DFromAngle(angle, pitch, speed);
return 0;
}
// This combines all 3 variations of the internal function
static void Thrust(AActor *self, double speed, double angle)
{
if (speed == 1e37)
{
self->Thrust();
}
else
{
if (angle == 1e37)
{
self->Thrust(speed);
}
else
{
self->Thrust(DAngle::fromDeg(angle), speed);
}
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Thrust, Thrust)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(speed);
PARAM_FLOAT(angle);
Thrust(self, speed, angle);
return 0;
}
static double AngleTo(AActor *self, AActor *targ, bool absolute)
{
return self->AngleTo(PARAM_NULLCHECK(targ, targ), absolute).Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, AngleTo, AngleTo)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(targ, AActor);
PARAM_BOOL(absolute);
ACTION_RETURN_FLOAT(self->AngleTo(targ, absolute).Degrees());
}
static void AngleToVector(double angle, double length, DVector2 *result)
{
*result = DAngle::fromDeg(angle).ToVector(length);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, AngleToVector, AngleToVector)
{
PARAM_PROLOGUE;
PARAM_ANGLE(angle);
PARAM_FLOAT(length);
ACTION_RETURN_VEC2(angle.ToVector(length));
}
static void RotateVector(double x, double y, double angle, DVector2 *result)
{
*result = DVector2(x, y).Rotated(angle);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RotateVector, RotateVector)
{
PARAM_PROLOGUE;
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_ANGLE(angle);
ACTION_RETURN_VEC2(DVector2(x, y).Rotated(angle));
}
static double Normalize180(double angle)
{
return DAngle::fromDeg(angle).Normalized180().Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Normalize180, Normalize180)
{
PARAM_PROLOGUE;
PARAM_ANGLE(angle);
ACTION_RETURN_FLOAT(angle.Normalized180().Degrees());
}
static double DistanceBySpeed(AActor *self, AActor *targ, double speed)
{
return self->DistanceBySpeed(PARAM_NULLCHECK(targ, targ), speed);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, DistanceBySpeed, DistanceBySpeed)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(targ, AActor);
PARAM_FLOAT(speed);
ACTION_RETURN_FLOAT(self->DistanceBySpeed(targ, speed));
}
static void SetXYZ(AActor *self, double x, double y, double z)
{
self->SetXYZ(x, y, z);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetXYZ, SetXYZ)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
self->SetXYZ(x, y, z);
return 0;
}
static void Vec2Angle(AActor *self, double length, double angle, bool absolute, DVector2 *result)
{
*result = self->Vec2Angle(length, DAngle::fromDeg(angle), absolute);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec2Angle, Vec2Angle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(length);
PARAM_ANGLE(angle);
PARAM_BOOL(absolute);
ACTION_RETURN_VEC2(self->Vec2Angle(length, angle, absolute));
}
static void Vec3To(AActor *self, AActor *t, DVector3 *result)
{
*result = self->Vec3To(PARAM_NULLCHECK(t, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec3To, Vec3To)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(t, AActor)
ACTION_RETURN_VEC3(self->Vec3To(t));
}
static void Vec2To(AActor *self, AActor *t, DVector2 *result)
{
*result = self->Vec2To(PARAM_NULLCHECK(t, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec2To, Vec2To)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(t, AActor)
ACTION_RETURN_VEC2(self->Vec2To(t));
}
static void Vec3Angle(AActor *self, double length, double angle, double z, bool absolute, DVector3 *result)
{
*result = self->Vec3Angle(length, DAngle::fromDeg(angle), z, absolute);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec3Angle, Vec3Angle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(length)
PARAM_ANGLE(angle);
PARAM_FLOAT(z);
PARAM_BOOL(absolute);
ACTION_RETURN_VEC3(self->Vec3Angle(length, angle, z, absolute));
}
static void Vec2OffsetZ(AActor *self, double x, double y, double z, bool absolute, DVector3 *result)
{
*result = self->Vec2OffsetZ(x, y, z, absolute);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec2OffsetZ, Vec2OffsetZ)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_BOOL(absolute);
ACTION_RETURN_VEC3(self->Vec2OffsetZ(x, y, z, absolute));
}
static void Vec2Offset(AActor *self, double x, double y, bool absolute, DVector2 *result)
{
*result = self->Vec2Offset(x, y, absolute);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec2Offset, Vec2Offset)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_BOOL(absolute);
ACTION_RETURN_VEC2(self->Vec2Offset(x, y, absolute));
}
static void Vec3Offset(AActor *self, double x, double y, double z, bool absolute, DVector3 *result)
{
*result = self->Vec3Offset(x, y, z, absolute);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Vec3Offset, Vec3Offset)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_BOOL(absolute);
ACTION_RETURN_VEC3(self->Vec3Offset(x, y, z, absolute));
}
static void ZS_PosRelative(AActor *self, sector_t *sec, DVector3 *result)
{
*result = self->PosRelative(sec);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, PosRelative, ZS_PosRelative)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER(sec, sector_t);
ACTION_RETURN_VEC3(self->PosRelative(sec));
}
static void RestoreDamage(AActor *self)
{
self->DamageVal = self->GetDefault()->DamageVal;
self->DamageFunc = self->GetDefault()->DamageFunc;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RestoreDamage, RestoreDamage)
{
PARAM_SELF_PROLOGUE(AActor);
RestoreDamage(self);
return 0;
}
static int PlayerNumber(AActor *self)
{
return self->player ? self->Level->PlayerNum(self->player) : 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, PlayerNumber, PlayerNumber)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(PlayerNumber(self));
}
static void SetFriendPlayer(AActor *self, player_t *player)
{
self->SetFriendPlayer(player);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetFriendPlayer, SetFriendPlayer)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER(player, player_t);
self->SetFriendPlayer(player);
return 0;
}
void ClearBounce(AActor *self)
{
self->BounceFlags = 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearBounce, ClearBounce)
{
PARAM_SELF_PROLOGUE(AActor);
ClearBounce(self);
return 0;
}
static int CountsAsKill(AActor *self)
{
return self->CountsAsKill();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CountsAsKill, CountsAsKill)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(self->CountsAsKill());
}
static int IsZeroDamage(AActor *self)
{
return self->IsZeroDamage();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, IsZeroDamage, IsZeroDamage)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(self->IsZeroDamage());
}
static void ClearInterpolation(AActor *self)
{
self->ClearInterpolation();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearInterpolation, ClearInterpolation)
{
PARAM_SELF_PROLOGUE(AActor);
self->ClearInterpolation();
return 0;
}
static int ApplyDamageFactors(PClassActor *itemcls, int damagetype, int damage, int defdamage)
{
DmgFactors &df = itemcls->ActorInfo()->DamageFactors;
if (df.Size() != 0)
{
return (df.Apply(ENamedName(damagetype), damage));
}
else
{
return (defdamage);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ApplyDamageFactors, ApplyDamageFactors)
{
PARAM_PROLOGUE;
PARAM_CLASS(itemcls, AActor);
PARAM_NAME(damagetype);
PARAM_INT(damage);
PARAM_INT(defdamage);
ACTION_RETURN_INT(ApplyDamageFactors(itemcls, damagetype.GetIndex(), damage, defdamage));
}
static void RestoreSpecialPosition(AActor *self)
{
self->RestoreSpecialPosition();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_RestoreSpecialPosition, RestoreSpecialPosition)
{
PARAM_SELF_PROLOGUE(AActor);
self->RestoreSpecialPosition();
return 0;
}
static double GetBobOffset(AActor *self, double frac)
{
return self->GetBobOffset(frac);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetBobOffset, GetBobOffset)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(frac);
ACTION_RETURN_FLOAT(self->GetBobOffset(frac));
}
static void SetIdle(AActor *self, bool nofunction)
{
self->SetIdle(nofunction);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetIdle, SetIdle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(nofunction);
self->SetIdle(nofunction);
return 0;
}
static int SpawnHealth(AActor *self)
{
return self->SpawnHealth();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SpawnHealth, SpawnHealth)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(self->SpawnHealth());
}
// Why does this exist twice?
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetSpawnHealth, SpawnHealth)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(self->SpawnHealth());
}
void Revive(AActor *self)
{
self->Revive();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Revive, Revive)
{
PARAM_SELF_PROLOGUE(AActor);
self->Revive();
return 0;
}
static double GetCameraHeight(AActor *self)
{
return self->GetCameraHeight();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetCameraHeight, GetCameraHeight)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_FLOAT(self->GetCameraHeight());
}
static FDropItem *GetDropItems(AActor *self)
{
return self->GetDropItems();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetDropItems, GetDropItems)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_POINTER(self->GetDropItems());
}
static double GetGravity(AActor *self)
{
return self->GetGravity();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetGravity, GetGravity)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_FLOAT(self->GetGravity());
}
static void GetTag(AActor *self, const FString &def, FString *result)
{
*result = self->GetTag(def.Len() == 0 ? nullptr : def.GetChars());
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetTag, GetTag)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_STRING(def);
FString res;
GetTag(self, def, &res);
ACTION_RETURN_STRING(res);
}
static void GetCharacterName(AActor *self, FString *result)
{
*result = self->GetCharacterName();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetCharacterName, GetCharacterName)
{
PARAM_SELF_PROLOGUE(AActor);
FString res;
GetCharacterName(self, &res);
ACTION_RETURN_STRING(res);
}
static void SetTag(AActor *self, const FString &def)
{
if (def.IsEmpty()) self->Tag = nullptr;
else self->Tag = self->mStringPropertyData.Alloc(def);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetTag, SetTag)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_STRING(def);
SetTag(self, def);
return 0;
}
static void ClearCounters(AActor *self)
{
self->ClearCounters();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearCounters, ClearCounters)
{
PARAM_SELF_PROLOGUE(AActor);
self->ClearCounters();
return 0;
}
static int GetModifiedDamage(AActor *self, int type, int damage, bool passive, AActor *inflictor, AActor *source, int flags)
{
return self->GetModifiedDamage(ENamedName(type), damage, passive, inflictor, source, flags);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetModifiedDamage, GetModifiedDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(type);
PARAM_INT(damage);
PARAM_BOOL(passive);
PARAM_OBJECT(inflictor, AActor);
PARAM_OBJECT(source, AActor);
PARAM_INT(flags);
ACTION_RETURN_INT(self->GetModifiedDamage(type, damage, passive, inflictor, source, flags));
}
static int ApplyDamageFactor(AActor *self, int type, int damage)
{
return self->ApplyDamageFactor(ENamedName(type), damage);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ApplyDamageFactor, ApplyDamageFactor)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(type);
PARAM_INT(damage);
ACTION_RETURN_INT(self->ApplyDamageFactor(type, damage));
}
double GetDefaultSpeed(PClassActor *type);
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetDefaultSpeed, GetDefaultSpeed)
{
PARAM_PROLOGUE;
PARAM_CLASS(type, AActor);
ACTION_RETURN_FLOAT(GetDefaultSpeed(type));
}
static int isTeammate(AActor *self, AActor *other)
{
return self->IsTeammate(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, isTeammate, isTeammate)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_BOOL(self->IsTeammate(other));
}
static int GetSpecies(AActor *self)
{
return self->GetSpecies().GetIndex();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetSpecies, GetSpecies)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(GetSpecies(self));
}
static int isFriend(AActor *self, AActor *other)
{
return self->IsFriend(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, isFriend, isFriend)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_BOOL(self->IsFriend(other));
}
static int isHostile(AActor *self, AActor *other)
{
return self->IsHostile(PARAM_NULLCHECK(other, other));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, isHostile, isHostile)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(other, AActor);
ACTION_RETURN_BOOL(self->IsHostile(other));
}
static FTerrainDef *GetFloorTerrain(AActor *self)
{
return &Terrains[P_GetThingFloorType(self)];
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetFloorTerrain, GetFloorTerrain)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_POINTER(GetFloorTerrain(self));
}
static int P_FindUniqueTID(FLevelLocals *Level, int start, int limit)
{
return Level->FindUniqueTID(start, limit);
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FindUniqueTid, P_FindUniqueTID)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_INT(start);
PARAM_INT(limit);
ACTION_RETURN_INT(P_FindUniqueTID(self, start, limit));
}
static void RemoveFromHash(AActor *self)
{
self->SetTID(0);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RemoveFromHash, RemoveFromHash)
{
PARAM_SELF_PROLOGUE(AActor);
RemoveFromHash(self);
return 0;
}
static void ChangeTid(AActor *self, int tid)
{
self->SetTID(tid);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ChangeTid, ChangeTid)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(tid);
ChangeTid(self, tid);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, FindFloorCeiling, P_FindFloorCeiling)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(flags);
P_FindFloorCeiling(self, flags);
return 0;
}
static int TeleportMove(AActor *self, double x, double y, double z, bool telefrag, bool modify)
{
return P_TeleportMove(self, DVector3(x, y, z), telefrag, modify);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TeleportMove, TeleportMove)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_BOOL(telefrag);
PARAM_BOOL(modify);
ACTION_RETURN_BOOL(P_TeleportMove(self, DVector3(x, y, z), telefrag, modify));
}
static double ZS_GetFriction(AActor *self, double *mf)
{
double friction;
*mf = P_GetMoveFactor(self, &friction);
return friction;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetFriction, ZS_GetFriction)
{
PARAM_SELF_PROLOGUE(AActor);
double friction, movefactor = P_GetMoveFactor(self, &friction);
if (numret > 1) ret[1].SetFloat(movefactor);
if (numret > 0) ret[0].SetFloat(friction);
return numret;
}
static int CheckPosition(AActor *self, double x, double y, bool actorsonly, FCheckPosition *tm)
{
if (tm)
{
return (P_CheckPosition(self, DVector2(x, y), *tm, actorsonly));
}
else
{
return (P_CheckPosition(self, DVector2(x, y), actorsonly));
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckPosition, CheckPosition)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_BOOL(actorsonly);
PARAM_POINTER(tm, FCheckPosition);
ACTION_RETURN_BOOL(CheckPosition(self, x, y, actorsonly, tm));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TestMobjLocation, P_TestMobjLocation)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(P_TestMobjLocation(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TestMobjZ, P_TestMobjZ)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(quick);
AActor *on = nullptr;
bool retv = P_TestMobjZ(self, quick, &on);
if (numret > 1) ret[1].SetObject(on);
if (numret > 0) ret[0].SetInt(retv);
return numret;
}
static int TryMove(AActor *self ,double x, double y, int dropoff, bool missilecheck, FCheckPosition *tm)
{
if (tm == nullptr)
{
return (P_TryMove(self, DVector2(x, y), dropoff, nullptr, missilecheck));
}
else
{
return (P_TryMove(self, DVector2(x, y), dropoff, nullptr, *tm, missilecheck));
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TryMove, TryMove)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(dropoff);
PARAM_BOOL(missilecheck);
PARAM_POINTER(tm, FCheckPosition);
ACTION_RETURN_BOOL(TryMove(self, x, y, dropoff, missilecheck, tm));
}
static int CheckMove(AActor *self ,double x, double y, int flags, FCheckPosition *tm)
{
if (tm == nullptr)
{
return (P_CheckMove(self, DVector2(x, y), flags));
}
else
{
return (P_CheckMove(self, DVector2(x, y), *tm, flags));
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckMove, CheckMove)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(flags);
PARAM_POINTER(tm, FCheckPosition);
ACTION_RETURN_BOOL(CheckMove(self, x, y, flags, tm));
}
static double AimLineAttack(AActor *self, double angle, double distance, FTranslatedLineTarget *pLineTarget, double vrange, int flags, AActor *target, AActor *friender)
{
flags &= ~ALF_IGNORENOAUTOAIM; // just to be safe. This flag is not supposed to be accesible to scripting.
return P_AimLineAttack(self, DAngle::fromDeg(angle), distance, pLineTarget, DAngle::fromDeg(vrange), flags, target, friender).Degrees();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, AimLineAttack, AimLineAttack)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_ANGLE(angle);
PARAM_FLOAT(distance);
PARAM_OUTPOINTER(pLineTarget, FTranslatedLineTarget);
PARAM_ANGLE(vrange);
PARAM_INT(flags);
PARAM_OBJECT(target, AActor);
PARAM_OBJECT(friender, AActor);
ACTION_RETURN_FLOAT(P_AimLineAttack(self, angle, distance, pLineTarget, vrange, flags, target, friender).Degrees());
}
static AActor *ZS_LineAttack(AActor *self, double angle, double distance, double pitch, int damage, int damageType, PClassActor *puffType, int flags, FTranslatedLineTarget *victim, double offsetz, double offsetforward, double offsetside, int *actualdamage)
{
if (puffType == nullptr) puffType = PClass::FindActor(NAME_BulletPuff); // P_LineAttack does not work without a puff to take info from.
return P_LineAttack(self, DAngle::fromDeg(angle), distance, DAngle::fromDeg(pitch), damage, ENamedName(damageType), puffType, flags, victim, actualdamage, offsetz, offsetforward, offsetside);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LineAttack, ZS_LineAttack)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(angle);
PARAM_FLOAT(distance);
PARAM_FLOAT(pitch);
PARAM_INT(damage);
PARAM_INT(damageType);
PARAM_CLASS(puffType, AActor);
PARAM_INT(flags);
PARAM_OUTPOINTER(victim, FTranslatedLineTarget);
PARAM_FLOAT(offsetz);
PARAM_FLOAT(offsetforward);
PARAM_FLOAT(offsetside);
int acdmg;
auto puff = ZS_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, offsetz, offsetforward, offsetside, &acdmg);
if (numret > 0) ret[0].SetObject(puff);
if (numret > 1) ret[1].SetInt(acdmg), numret = 2;
return numret;
}
static int LineTrace(AActor *self, double angle, double distance, double pitch, int flags, double offsetz, double offsetforward, double offsetside, FLineTraceData *data)
{
return P_LineTrace(self,DAngle::fromDeg(angle),distance,DAngle::fromDeg(pitch),flags,offsetz,offsetforward,offsetside,data);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LineTrace, LineTrace)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(angle);
PARAM_FLOAT(distance);
PARAM_FLOAT(pitch);
PARAM_INT(flags);
PARAM_FLOAT(offsetz);
PARAM_FLOAT(offsetforward);
PARAM_FLOAT(offsetside);
PARAM_OUTPOINTER(data, FLineTraceData);
ACTION_RETURN_BOOL(P_LineTrace(self,DAngle::fromDeg(angle),distance,DAngle::fromDeg(pitch),flags,offsetz,offsetforward,offsetside,data));
}
static void TraceBleedAngle(AActor *self, int damage, double angle, double pitch)
{
P_TraceBleed(damage, self, DAngle::fromDeg(angle), DAngle::fromDeg(pitch));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TraceBleedAngle, TraceBleedAngle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(damage);
PARAM_FLOAT(angle);
PARAM_FLOAT(pitch);
P_TraceBleed(damage, self, DAngle::fromDeg(angle), DAngle::fromDeg(pitch));
return 0;
}
static void TraceBleedTLT(FTranslatedLineTarget *self, int damage, AActor *missile)
{
P_TraceBleed(damage, self, PARAM_NULLCHECK(missile, missile));
}
DEFINE_ACTION_FUNCTION_NATIVE(_FTranslatedLineTarget, TraceBleed, TraceBleedTLT)
{
PARAM_SELF_STRUCT_PROLOGUE(FTranslatedLineTarget);
PARAM_INT(damage);
PARAM_OBJECT_NOT_NULL(missile, AActor);
P_TraceBleed(damage, self, missile);
return 0;
}
static void TraceBleedA(AActor *self, int damage, AActor *missile)
{
if (missile) P_TraceBleed(damage, self, missile);
else P_TraceBleed(damage, self);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, TraceBleed, TraceBleedA)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(damage);
PARAM_OBJECT(missile, AActor);
TraceBleedA(self, damage, missile);
return 0;
}
static void RailAttack(AActor *self, FRailParams *p)
{
p->source = self;
P_RailAttack(p);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RailAttack, RailAttack)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER(p, FRailParams);
RailAttack(self, p);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, UsePuzzleItem, P_UsePuzzleItem)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(puzznum);
ACTION_RETURN_BOOL(P_UsePuzzleItem(self, puzznum));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetRadiusDamage, P_GetRadiusDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(thing, AActor);
PARAM_INT(damage);
PARAM_INT(distance);
PARAM_INT(fulldmgdistance);
PARAM_BOOL(oldradiusdmg);
ACTION_RETURN_INT(P_GetRadiusDamage(self, thing, damage, distance, fulldmgdistance, oldradiusdmg));
}
static int RadiusAttack(AActor *self, AActor *bombsource, int bombdamage, int bombdistance, int damagetype, int flags, int fulldamagedistance, int species)
{
return P_RadiusAttack(self, bombsource, bombdamage, bombdistance, ENamedName(damagetype), flags, fulldamagedistance, ENamedName(species));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RadiusAttack, RadiusAttack)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(bombsource, AActor);
PARAM_INT(bombdamage);
PARAM_INT(bombdistance);
PARAM_INT(damagetype);
PARAM_INT(flags);
PARAM_INT(fulldamagedistance);
PARAM_INT(species);
ACTION_RETURN_INT(RadiusAttack(self, bombsource, bombdamage, bombdistance, damagetype, flags, fulldamagedistance, species));
}
static int ZS_GetSpriteIndex(int sprt)
{
return GetSpriteIndex(FName(ENamedName(sprt)).GetChars(), false);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetSpriteIndex, ZS_GetSpriteIndex)
{
PARAM_PROLOGUE;
PARAM_INT(sprt);
ACTION_RETURN_INT(ZS_GetSpriteIndex(sprt));
}
static PClassActor *ZS_GetReplacement(PClassActor *c)
{
return c->GetReplacement(currentVMLevel);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetReplacement, ZS_GetReplacement)
{
PARAM_PROLOGUE;
PARAM_POINTER(c, PClassActor);
ACTION_RETURN_POINTER(ZS_GetReplacement(c));
}
static PClassActor *ZS_GetReplacee(PClassActor *c)
{
return c->GetReplacee(currentVMLevel);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetReplacee, ZS_GetReplacee)
{
PARAM_PROLOGUE;
PARAM_POINTER(c, PClassActor);
ACTION_RETURN_POINTER(ZS_GetReplacee(c));
}
static void DrawSplash(AActor *self, int count, double angle, int kind)
{
P_DrawSplash(self->Level, count, self->Pos(), DAngle::fromDeg(angle), kind);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(count);
PARAM_FLOAT(angle);
PARAM_INT(kind);
P_DrawSplash(self->Level, count, self->Pos(), DAngle::fromDeg(angle), kind);
return 0;
}
static void UnlinkFromWorld(AActor *self, FLinkContext *ctx)
{
self->UnlinkFromWorld(ctx);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, UnlinkFromWorld, UnlinkFromWorld)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER(ctx, FLinkContext);
self->UnlinkFromWorld(ctx); // fixme
return 0;
}
static void LinkToWorld(AActor *self, FLinkContext *ctx)
{
self->LinkToWorld(ctx);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LinkToWorld, LinkToWorld)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER(ctx, FLinkContext);
self->LinkToWorld(ctx);
return 0;
}
static void SetOrigin(AActor *self, double x, double y, double z, bool moving)
{
self->SetOrigin(x, y, z, moving);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetOrigin, SetOrigin)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_BOOL(moving);
self->SetOrigin(x, y, z, moving);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RoughMonsterSearch, P_RoughMonsterSearch)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(distance);
PARAM_BOOL(onlyseekable);
PARAM_BOOL(frontonly);
PARAM_FLOAT(fov);
ACTION_RETURN_OBJECT(P_RoughMonsterSearch(self, distance, onlyseekable, frontonly, fov));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckSight, P_CheckSight)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(target, AActor);
PARAM_INT(flags);
ACTION_RETURN_BOOL(P_CheckSight(self, target, flags));
}
static void GiveSecret(AActor *self, bool printmessage, bool playsound)
{
P_GiveSecret(self->Level, self, printmessage, playsound, -1);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GiveSecret, GiveSecret)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(printmessage);
PARAM_BOOL(playsound);
GiveSecret(self, printmessage, playsound);
return 0;
}
static int ZS_GetMissileDamage(AActor *self, int mask, int add, int pick_pointer)
{
self = COPY_AAPTR(self, pick_pointer);
return self ? self->GetMissileDamage(mask, add) : 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetMissileDamage, ZS_GetMissileDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(mask);
PARAM_INT(add);
PARAM_INT(pick_pointer);
ACTION_RETURN_INT(ZS_GetMissileDamage(self, mask, add, pick_pointer));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SoundAlert, P_NoiseAlert)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(target, AActor);
PARAM_BOOL(splash);
PARAM_FLOAT(maxdist);
P_NoiseAlert(self, target, splash, maxdist);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, HitFriend, P_HitFriend)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(P_HitFriend(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, MonsterMove, P_SmartMove)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(P_SmartMove(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, NewChaseDir, P_NewChaseDir)
{
PARAM_SELF_PROLOGUE(AActor);
P_NewChaseDir(self);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RandomChaseDir, P_RandomChaseDir)
{
PARAM_SELF_PROLOGUE(AActor);
P_RandomChaseDir(self);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, IsVisible, P_IsVisible)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(other, AActor);
PARAM_BOOL(allaround);
PARAM_POINTER(params, FLookExParams);
ACTION_RETURN_BOOL(P_IsVisible(self, other, allaround, params));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LookForMonsters, P_LookForMonsters)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(P_LookForMonsters(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LookForTID, P_LookForTID)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(allaround);
PARAM_POINTER(params, FLookExParams);
ACTION_RETURN_BOOL(P_LookForTID(self, allaround, params));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LookForEnemies, P_LookForEnemies)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(allaround);
PARAM_POINTER(params, FLookExParams);
ACTION_RETURN_BOOL(P_LookForEnemies(self, allaround, params));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, LookForPlayers, P_LookForPlayers)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(allaround);
PARAM_POINTER(params, FLookExParams);
ACTION_RETURN_BOOL(P_LookForPlayers(self, allaround, params));
}
static int CheckMonsterUseSpecials(AActor *self)
{
spechit_t spec;
int good = 0;
if (!(self->flags6 & MF6_NOTRIGGER))
{
while (spechit.Pop (spec))
{
// [RH] let monsters push lines, as well as use them
if (((self->flags4 & MF4_CANUSEWALLS) && P_ActivateLine (spec.line, self, 0, SPAC_Use)) ||
((self->flags2 & MF2_PUSHWALL) && P_ActivateLine (spec.line, self, 0, SPAC_Push)))
{
good |= spec.line == self->BlockingLine ? 1 : 2;
}
}
}
else spechit.Clear();
return good;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckMonsterUseSpecials, CheckMonsterUseSpecials)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(CheckMonsterUseSpecials(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_Wander, A_Wander)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(flags);
A_Wander(self, flags);
return 0;
}
//==========================================================================
//
// A_Chase and variations
//
//==========================================================================
static void A_FastChase(AActor *self)
{
A_DoChase(self, true, self->MeleeState, self->MissileState, true, true, false, 0);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_FastChase, A_FastChase)
{
PARAM_SELF_PROLOGUE(AActor);
A_FastChase(self);
return 0;
}
static void A_VileChase(AActor *self)
{
if (!P_CheckForResurrection(self, true))
{
A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_VileChase, A_VileChase)
{
PARAM_SELF_PROLOGUE(AActor);
A_VileChase(self);
return 0;
}
static void A_ExtChase(AActor *self, bool domelee, bool domissile, bool playactive, bool nightmarefast)
{
// Now that A_Chase can handle state label parameters, this function has become rather useless...
A_DoChase(self, false,
domelee ? self->MeleeState : NULL, domissile ? self->MissileState : NULL,
playactive, nightmarefast, false, 0);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_ExtChase, A_ExtChase)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(domelee);
PARAM_BOOL(domissile);
PARAM_BOOL(playactive);
PARAM_BOOL(nightmarefast);
A_ExtChase(self, domelee, domissile, playactive, nightmarefast);
return 0;
}
int CheckForResurrection(AActor *self, FState* state, int sound)
{
return P_CheckForResurrection(self, false, state, sound);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_CheckForResurrection, CheckForResurrection)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_STATE(state);
PARAM_INT(sound);
ACTION_RETURN_BOOL(P_CheckForResurrection(self, false, state, sound));
}
static void ZS_Face(AActor *self, AActor *faceto, double max_turn, double max_pitch, double ang_offset, double pitch_offset, int flags, double z_add)
{
A_Face(self, faceto, DAngle::fromDeg(max_turn), DAngle::fromDeg(max_pitch), DAngle::fromDeg(ang_offset), DAngle::fromDeg(pitch_offset), flags, z_add);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_Face, ZS_Face)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(faceto, AActor)
PARAM_ANGLE(max_turn)
PARAM_ANGLE(max_pitch)
PARAM_ANGLE(ang_offset)
PARAM_ANGLE(pitch_offset)
PARAM_INT(flags)
PARAM_FLOAT(z_add)
A_Face(self, faceto, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckBossDeath, CheckBossDeath)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(CheckBossDeath(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_BossDeath, A_BossDeath)
{
PARAM_SELF_PROLOGUE(AActor);
A_BossDeath(self);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Substitute, StaticPointerSubstitution)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(replace, AActor);
StaticPointerSubstitution(self, replace);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(_PlayerPawn, Substitute, StaticPointerSubstitution)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(replace, AActor);
StaticPointerSubstitution(self, replace);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(_MorphedMonster, Substitute, StaticPointerSubstitution)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(replace, AActor);
StaticPointerSubstitution(self, replace);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetSpawnableType, P_GetSpawnableType)
{
PARAM_PROLOGUE;
PARAM_INT(num);
ACTION_RETURN_POINTER(P_GetSpawnableType(num));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_NoBlocking, A_Unblock)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(drop);
A_Unblock(self, drop);
return 0;
}
static void CopyBloodColor(AActor* self, AActor* other)
{
if (self && other)
{
self->BloodColor = other->BloodColor;
self->BloodTranslation = other->BloodTranslation;
}
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CopyBloodColor, CopyBloodColor)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(other, AActor);
CopyBloodColor(self, other);
return 0;
}
//=====================================================================================
//
// Inventory exports
//
//=====================================================================================
DEFINE_ACTION_FUNCTION_NATIVE(AInventory, PrintPickupMessage, PrintPickupMessage)
{
PARAM_PROLOGUE;
PARAM_BOOL(localview);
PARAM_STRING(str);
PrintPickupMessage(localview, str);
return 0;
}
//=====================================================================================
//
// Key exports
//
//=====================================================================================
DEFINE_ACTION_FUNCTION_NATIVE(AKey, GetKeyTypeCount, P_GetKeyTypeCount)
{
PARAM_PROLOGUE;
ACTION_RETURN_INT(P_GetKeyTypeCount());
}
DEFINE_ACTION_FUNCTION_NATIVE(AKey, GetKeyType, P_GetKeyType)
{
PARAM_PROLOGUE;
PARAM_INT(num);
ACTION_RETURN_POINTER(P_GetKeyType(num));
}
//=====================================================================================
//
// 3D Floor exports
//
//=====================================================================================
int CheckFor3DFloorHit(AActor *self, double z, bool trigger)
{
return P_CheckFor3DFloorHit(self, z, trigger);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFor3DFloorHit, CheckFor3DFloorHit)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(z);
PARAM_BOOL(trigger);
ACTION_RETURN_BOOL(P_CheckFor3DFloorHit(self, z, trigger));
}
int CheckFor3DCeilingHit(AActor *self, double z, bool trigger)
{
return P_CheckFor3DCeilingHit(self, z, trigger);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFor3DCeilingHit, CheckFor3DCeilingHit)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(z);
PARAM_BOOL(trigger);
ACTION_RETURN_BOOL(P_CheckFor3DCeilingHit(self, z, trigger));
}
static int isFrozen(AActor *self)
{
return self->isFrozen();
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, isFrozen, isFrozen)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(isFrozen(self));
}
//===========================================================================
//
// PlayerPawn functions
//
//===========================================================================
DEFINE_ACTION_FUNCTION_NATIVE(APlayerPawn, MarkPlayerSounds, S_MarkPlayerSounds)
{
PARAM_SELF_PROLOGUE(AActor);
S_MarkPlayerSounds(self);
return 0;
}
static void GetPrintableDisplayNameJit(PClassActor *cls, FString *result)
{
*result = cls->GetDisplayName();
}
DEFINE_ACTION_FUNCTION_NATIVE(APlayerPawn, GetPrintableDisplayName, GetPrintableDisplayNameJit)
{
PARAM_PROLOGUE;
PARAM_CLASS(type, AActor);
ACTION_RETURN_STRING(type->GetDisplayName());
}
static void SetViewPos(AActor *self, double x, double y, double z, int flags)
{
if (!self->ViewPos)
{
self->ViewPos = Create<DViewPosition>();
}
DVector3 pos = { x,y,z };
self->ViewPos->Set(pos, flags);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetViewPos, SetViewPos)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_INT(flags);
SetViewPos(self, x, y, z, flags);
return 0;
}
IMPLEMENT_CLASS(DViewPosition, false, false);
DEFINE_FIELD_X(ViewPosition, DViewPosition, Offset)
DEFINE_FIELD_X(ViewPosition, DViewPosition, Flags)
DEFINE_FIELD(DThinker, Level)
DEFINE_FIELD(AActor, snext)
DEFINE_FIELD(AActor, player)
DEFINE_FIELD_NAMED(AActor, __Pos, pos)
DEFINE_FIELD_NAMED(AActor, __Pos.X, x)
DEFINE_FIELD_NAMED(AActor, __Pos.Y, y)
DEFINE_FIELD_NAMED(AActor, __Pos.Z, z)
DEFINE_FIELD(AActor, SpriteOffset)
DEFINE_FIELD(AActor, WorldOffset)
DEFINE_FIELD(AActor, Prev)
DEFINE_FIELD(AActor, SpriteAngle)
DEFINE_FIELD(AActor, SpriteRotation)
DEFINE_FIELD(AActor, VisibleStartAngle)
DEFINE_FIELD(AActor, VisibleStartPitch)
DEFINE_FIELD(AActor, VisibleEndAngle)
DEFINE_FIELD(AActor, VisibleEndPitch)
DEFINE_FIELD_NAMED(AActor, Angles.Yaw, angle)
DEFINE_FIELD_NAMED(AActor, Angles.Pitch, pitch)
DEFINE_FIELD_NAMED(AActor, Angles.Roll, roll)
DEFINE_FIELD(AActor, Vel)
DEFINE_FIELD_NAMED(AActor, Vel.X, velx)
DEFINE_FIELD_NAMED(AActor, Vel.Y, vely)
DEFINE_FIELD_NAMED(AActor, Vel.Z, velz)
DEFINE_FIELD_NAMED(AActor, Vel.X, momx)
DEFINE_FIELD_NAMED(AActor, Vel.Y, momy)
DEFINE_FIELD_NAMED(AActor, Vel.Z, momz)
DEFINE_FIELD(AActor, Speed)
DEFINE_FIELD(AActor, FloatSpeed)
DEFINE_FIELD(AActor, sprite)
DEFINE_FIELD(AActor, frame)
DEFINE_FIELD(AActor, Scale)
DEFINE_FIELD_NAMED(AActor, Scale.X, scalex)
DEFINE_FIELD_NAMED(AActor, Scale.Y, scaley)
DEFINE_FIELD(AActor, RenderStyle)
DEFINE_FIELD(AActor, picnum)
DEFINE_FIELD(AActor, Alpha)
DEFINE_FIELD(AActor, fillcolor)
DEFINE_FIELD_NAMED(AActor, Sector, CurSector) // clashes with type 'sector'.
DEFINE_FIELD(AActor, subsector)
DEFINE_FIELD(AActor, ceilingz)
DEFINE_FIELD(AActor, floorz)
DEFINE_FIELD(AActor, dropoffz)
DEFINE_FIELD(AActor, floorsector)
DEFINE_FIELD(AActor, floorpic)
DEFINE_FIELD(AActor, floorterrain)
DEFINE_FIELD(AActor, ceilingsector)
DEFINE_FIELD(AActor, ceilingpic)
DEFINE_FIELD(AActor, Height)
DEFINE_FIELD(AActor, radius)
DEFINE_FIELD(AActor, renderradius)
DEFINE_FIELD(AActor, projectilepassheight)
DEFINE_FIELD(AActor, tics)
DEFINE_FIELD_NAMED(AActor, state, curstate) // clashes with type 'state'.
DEFINE_FIELD_NAMED(AActor, DamageVal, Damage) // name differs for historic reasons
DEFINE_FIELD(AActor, projectileKickback)
DEFINE_FIELD(AActor, VisibleToTeam)
DEFINE_FIELD(AActor, special1)
DEFINE_FIELD(AActor, special2)
DEFINE_FIELD(AActor, specialf1)
DEFINE_FIELD(AActor, specialf2)
DEFINE_FIELD(AActor, weaponspecial)
DEFINE_FIELD(AActor, health)
DEFINE_FIELD(AActor, movedir)
DEFINE_FIELD(AActor, visdir)
DEFINE_FIELD(AActor, movecount)
DEFINE_FIELD(AActor, strafecount)
DEFINE_FIELD(AActor, target)
DEFINE_FIELD(AActor, master)
DEFINE_FIELD(AActor, tracer)
DEFINE_FIELD(AActor, LastHeard)
DEFINE_FIELD(AActor, lastenemy)
DEFINE_FIELD(AActor, LastLookActor)
DEFINE_FIELD(AActor, reactiontime)
DEFINE_FIELD(AActor, threshold)
DEFINE_FIELD(AActor, DefThreshold)
DEFINE_FIELD(AActor, SpawnPoint)
DEFINE_FIELD(AActor, SpawnAngle)
DEFINE_FIELD(AActor, StartHealth)
DEFINE_FIELD(AActor, WeaveIndexXY)
DEFINE_FIELD(AActor, WeaveIndexZ)
DEFINE_FIELD(AActor, skillrespawncount)
DEFINE_FIELD(AActor, args)
DEFINE_FIELD(AActor, Mass)
DEFINE_FIELD(AActor, special)
DEFINE_FIELD(AActor, tid)
DEFINE_FIELD(AActor, TIDtoHate)
DEFINE_FIELD(AActor, waterlevel)
DEFINE_FIELD(AActor, waterdepth)
DEFINE_FIELD(AActor, Score)
DEFINE_FIELD(AActor, accuracy)
DEFINE_FIELD(AActor, stamina)
DEFINE_FIELD(AActor, meleerange)
DEFINE_FIELD(AActor, PainThreshold)
DEFINE_FIELD(AActor, Gravity)
DEFINE_FIELD(AActor, Floorclip)
DEFINE_FIELD(AActor, DamageType)
DEFINE_FIELD(AActor, DamageTypeReceived)
DEFINE_FIELD(AActor, FloatBobPhase)
DEFINE_FIELD(AActor, FloatBobStrength)
DEFINE_FIELD(AActor, RipperLevel)
DEFINE_FIELD(AActor, RipLevelMin)
DEFINE_FIELD(AActor, RipLevelMax)
DEFINE_FIELD(AActor, Species)
DEFINE_FIELD(AActor, alternative)
DEFINE_FIELD(AActor, goal)
DEFINE_FIELD(AActor, MinMissileChance)
DEFINE_FIELD(AActor, LastLookPlayerNumber)
DEFINE_FIELD(AActor, SpawnFlags)
DEFINE_FIELD(AActor, meleethreshold)
DEFINE_FIELD(AActor, maxtargetrange)
DEFINE_FIELD(AActor, bouncefactor)
DEFINE_FIELD(AActor, wallbouncefactor)
DEFINE_FIELD(AActor, bouncecount)
DEFINE_FIELD(AActor, Friction)
DEFINE_FIELD(AActor, FastChaseStrafeCount)
DEFINE_FIELD(AActor, pushfactor)
DEFINE_FIELD(AActor, lastpush)
DEFINE_FIELD(AActor, activationtype)
DEFINE_FIELD(AActor, lastbump)
DEFINE_FIELD(AActor, DesignatedTeam)
DEFINE_FIELD(AActor, BlockingMobj)
DEFINE_FIELD(AActor, BlockingLine)
DEFINE_FIELD(AActor, Blocking3DFloor)
DEFINE_FIELD(AActor, BlockingCeiling)
DEFINE_FIELD(AActor, BlockingFloor)
DEFINE_FIELD(AActor, freezetics)
DEFINE_FIELD(AActor, PoisonDamage)
DEFINE_FIELD(AActor, PoisonDamageType)
DEFINE_FIELD(AActor, PoisonDuration)
DEFINE_FIELD(AActor, PoisonPeriod)
DEFINE_FIELD(AActor, PoisonDamageReceived)
DEFINE_FIELD(AActor, PoisonDamageTypeReceived)
DEFINE_FIELD(AActor, PoisonDurationReceived)
DEFINE_FIELD(AActor, PoisonPeriodReceived)
DEFINE_FIELD(AActor, Poisoner)
DEFINE_FIELD_NAMED(AActor, Inventory, Inv) // clashes with type 'Inventory'.
DEFINE_FIELD(AActor, smokecounter)
DEFINE_FIELD(AActor, FriendPlayer)
DEFINE_FIELD(AActor, Translation)
DEFINE_FIELD(AActor, AttackSound)
DEFINE_FIELD(AActor, DeathSound)
DEFINE_FIELD(AActor, SeeSound)
DEFINE_FIELD(AActor, PainSound)
DEFINE_FIELD(AActor, ActiveSound)
DEFINE_FIELD(AActor, UseSound)
DEFINE_FIELD(AActor, BounceSound)
DEFINE_FIELD(AActor, WallBounceSound)
DEFINE_FIELD(AActor, CrushPainSound)
DEFINE_FIELD(AActor, MaxDropOffHeight)
DEFINE_FIELD(AActor, MaxStepHeight)
DEFINE_FIELD(AActor, MaxSlopeSteepness)
DEFINE_FIELD(AActor, PainChance)
DEFINE_FIELD(AActor, PainType)
DEFINE_FIELD(AActor, DeathType)
DEFINE_FIELD(AActor, DamageFactor)
DEFINE_FIELD(AActor, DamageMultiply)
DEFINE_FIELD(AActor, TeleFogSourceType)
DEFINE_FIELD(AActor, TeleFogDestType)
DEFINE_FIELD(AActor, SpawnState)
DEFINE_FIELD(AActor, SeeState)
DEFINE_FIELD(AActor, MeleeState)
DEFINE_FIELD(AActor, MissileState)
DEFINE_FIELD(AActor, ConversationRoot)
DEFINE_FIELD(AActor, Conversation)
DEFINE_FIELD(AActor, DecalGenerator)
DEFINE_FIELD(AActor, fountaincolor)
DEFINE_FIELD(AActor, CameraHeight)
DEFINE_FIELD(AActor, CameraFOV)
DEFINE_FIELD(AActor, RadiusDamageFactor)
DEFINE_FIELD(AActor, SelfDamageFactor)
DEFINE_FIELD(AActor, StealthAlpha)
DEFINE_FIELD(AActor, WoundHealth)
DEFINE_FIELD(AActor, BloodColor)
DEFINE_FIELD(AActor, BloodTranslation)
DEFINE_FIELD(AActor, RenderHidden)
DEFINE_FIELD(AActor, RenderRequired)
DEFINE_FIELD(AActor, friendlyseeblocks)
DEFINE_FIELD(AActor, SpawnTime)
DEFINE_FIELD(AActor, InventoryID)
DEFINE_FIELD(AActor, ThruBits)
DEFINE_FIELD(AActor, ViewPos)
DEFINE_FIELD_NAMED(AActor, ViewAngles.Yaw, viewangle)
DEFINE_FIELD_NAMED(AActor, ViewAngles.Pitch, viewpitch)
DEFINE_FIELD_NAMED(AActor, ViewAngles.Roll, viewroll)
DEFINE_FIELD(AActor, LightLevel)
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, thing);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos);
DEFINE_FIELD_NAMED_X(FCheckPosition, FCheckPosition, sector, cursector);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorz);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingz);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, dropoffz);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorpic);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorterrain);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorsector);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingpic);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingsector);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, touchmidtex);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, abovemidtex);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floatok);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, FromPMove);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingline);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, stepthing);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, DoRipping);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, portalstep);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, portalgroup);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, PushTime);
DEFINE_FIELD_X(FRailParams, FRailParams, source);
DEFINE_FIELD_X(FRailParams, FRailParams, damage);
DEFINE_FIELD_X(FRailParams, FRailParams, offset_xy);
DEFINE_FIELD_X(FRailParams, FRailParams, offset_z);
DEFINE_FIELD_X(FRailParams, FRailParams, color1);
DEFINE_FIELD_X(FRailParams, FRailParams, color2);
DEFINE_FIELD_X(FRailParams, FRailParams, maxdiff);
DEFINE_FIELD_X(FRailParams, FRailParams, flags);
DEFINE_FIELD_X(FRailParams, FRailParams, puff);
DEFINE_FIELD_X(FRailParams, FRailParams, angleoffset);
DEFINE_FIELD_X(FRailParams, FRailParams, pitchoffset);
DEFINE_FIELD_X(FRailParams, FRailParams, distance);
DEFINE_FIELD_X(FRailParams, FRailParams, duration);
DEFINE_FIELD_X(FRailParams, FRailParams, sparsity);
DEFINE_FIELD_X(FRailParams, FRailParams, drift);
DEFINE_FIELD_X(FRailParams, FRailParams, spawnclass);
DEFINE_FIELD_X(FRailParams, FRailParams, SpiralOffset);
DEFINE_FIELD_X(FRailParams, FRailParams, limit);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitActor);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLine);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitSector);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Hit3DFloor);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitTexture);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLocation);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitDir);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Distance);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, NumPortals);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LineSide);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LinePart);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, SectorPlane);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitType);