- moved declaration of native fields into the respective class definitions.

This bypasses a declaration in the script in favor of a simpler implementation. In order to work it is always necessary to have an offset table to map the variables to, but doing it fully on the native side only requires adding the type to the declaration.
This commit is contained in:
Christoph Oelckers 2016-11-04 00:19:36 +01:00
parent c9dad70408
commit 9563045305
9 changed files with 170 additions and 124 deletions

View File

@ -565,6 +565,7 @@ class DDropItem : public DObject
{
DECLARE_CLASS(DDropItem, DObject)
HAS_OBJECT_POINTERS
HAS_FIELDS
public:
DDropItem *Next;
FName Name;
@ -578,6 +579,7 @@ const double MinVel = EQUAL_EPSILON;
class AActor : public DThinker
{
DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
HAS_FIELDS
HAS_OBJECT_POINTERS
public:
AActor () throw();

View File

@ -62,6 +62,7 @@ ClassReg DObject::RegistrationInfo =
NULL, // ParentType
NULL, // Pointers
&DObject::InPlaceConstructor, // ConstructNative
&DObject::InitNativeFields,
sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum
};
@ -344,6 +345,18 @@ DObject::~DObject ()
//
//==========================================================================
void DObject::InitNativeFields()
{
auto meta = RUNTIME_CLASS(DObject);
meta->AddNativeField("bDestroyed", TypeSInt32, myoffsetof(DObject, ObjectFlags), VARF_ReadOnly, OF_EuthanizeMe);
}
//==========================================================================
//
//
//
//==========================================================================
void DObject::Destroy ()
{
ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;

View File

@ -111,6 +111,7 @@ struct ClassReg
ClassReg *ParentType;
const size_t *Pointers;
void (*ConstructNative)(void *);
void(*InitNatives)();
unsigned int SizeOf:28;
unsigned int MetaClassNum:4;
@ -147,6 +148,9 @@ protected: \
#define HAS_OBJECT_POINTERS \
static const size_t PointerOffsets[];
#define HAS_FIELDS \
static void InitNativeFields();
// Taking the address of a field in an object at address 1 instead of
// address 0 keeps GCC from complaining about possible misuse of offsetof.
#define DECLARE_POINTER(field) (size_t)&((ThisClass*)1)->field - 1,
@ -159,13 +163,14 @@ protected: \
# define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
#endif
#define _IMP_PCLASS(cls,ptrs,create) \
#define _IMP_PCLASS(cls,ptrs,create, initn) \
ClassReg cls::RegistrationInfo = {\
NULL, \
#cls, \
&cls::Super::RegistrationInfo, \
ptrs, \
create, \
initn, \
sizeof(cls), \
cls::MetaClassNum }; \
_DECLARE_TI(cls) \
@ -176,18 +181,27 @@ protected: \
#define IMPLEMENT_POINTY_CLASS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor) \
_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, nullptr) \
const size_t cls::PointerOffsets[] = {
#define IMPLEMENT_POINTY_CLASS_WITH_FIELDS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, cls::InitNativeFields) \
const size_t cls::PointerOffsets[] = {
#define IMPLEMENT_CLASS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,NULL,cls::InPlaceConstructor)
_IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, nullptr)
#define IMPLEMENT_CLASS_WITH_FIELDS(cls) \
_IMP_CREATE_OBJ(cls) \
_IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, cls::InitNativeFields)
#define IMPLEMENT_ABSTRACT_CLASS(cls) \
_IMP_PCLASS(cls,NULL,NULL)
_IMP_PCLASS(cls,nullptr,nullptr,nullptr)
#define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
_IMP_PCLASS(cls,cls::PointerOffsets,nullptr,nullptr) \
const size_t cls::PointerOffsets[] = {
enum EObjectFlags
@ -438,6 +452,7 @@ public:
virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
static void InPlaceConstructor (void *mem);
static void InitNativeFields();
typedef PClass MetaClass;
private:
typedef DObject ThisClass;

View File

@ -2309,13 +2309,18 @@ PField::PField()
{
}
PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue)
: PSymbol(name), Offset(offset), Type(type), Flags(flags)
{
BitValue = bitvalue;
if (bitvalue > -1)
if (bitvalue != -1)
{
if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(bitvalue) < 8 * type->Size)
BitValue = 0;
unsigned val = bitvalue;
while ((val >>= 1)) BitValue++;
if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(BitValue) < 8u * type->Size)
{
// map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values.
#ifndef __BIG_ENDIAN__

View File

@ -1856,13 +1856,6 @@ void FLevelLocals::AddScroller (int secnum)
//
//==========================================================================
inline int val2bit(int val)
{
int bit = 0;
while ((val >>= 1)) bit++;
return bit;
}
void G_InitLevelLocalsForScript()
{
PStruct *lstruct = NewStruct("LevelLocals", nullptr);
@ -1884,14 +1877,14 @@ void G_InitLevelLocalsForScript()
lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap));
lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap));
lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly);
lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_MONSTERSTELEFRAG));
lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_ACTOWNSPECIAL));
lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_SNDSEQTOTALCTRL));
lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_ALLMAP));
lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MISSILESACTIVATEIMPACT));
lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MONSTERFALLINGDAMAGE));
lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_CHECKSWITCHRANGE));
lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_POLYGRIND));
lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_MONSTERSTELEFRAG);
lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_ACTOWNSPECIAL);
lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_SNDSEQTOTALCTRL);
lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, (LEVEL2_ALLMAP));
lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MISSILESACTIVATEIMPACT);
lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MONSTERFALLINGDAMAGE);
lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_CHECKSWITCHRANGE);
lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_POLYGRIND);
lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly);
lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly);
lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly);

View File

@ -5389,11 +5389,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
{
if (!looping)
{
S_PlaySound(spot, chan, sid, vol, atten, local);
S_PlaySound(spot, chan, sid, vol, atten, !!local);
}
else if (!S_IsActorPlayingSomething(spot, chan & 7, sid))
{
S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, local);
S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, !!local);
}
}
}

View File

@ -131,7 +131,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
// CODE --------------------------------------------------------------------
IMPLEMENT_POINTY_CLASS (AActor)
IMPLEMENT_POINTY_CLASS_WITH_FIELDS (AActor)
DECLARE_POINTER (target)
DECLARE_POINTER (lastenemy)
DECLARE_POINTER (tracer)
@ -151,6 +151,99 @@ AActor::~AActor ()
// Use Destroy() instead.
}
extern FFlagDef InternalActorFlagDefs[];
extern FFlagDef ActorFlagDefs[];
void AActor::InitNativeFields()
{
PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));
PType *TypeInventory = NewPointer(RUNTIME_CLASS(AInventory));
PStruct *sstruct = NewStruct("Sector", nullptr);
auto TypeSector = NewPointer(sstruct);
PType *array5 = NewArray(TypeSInt32, 5);
auto meta = RUNTIME_CLASS(AActor);
// Define the member variables we feel like exposing to the user
meta->AddNativeField(NAME_Alpha, TypeFloat64, myoffsetof(AActor, Alpha));
meta->AddNativeField(NAME_Angle, TypeFloat64, myoffsetof(AActor, Angles.Yaw));
meta->AddNativeField(NAME_Args, array5, myoffsetof(AActor, args));
meta->AddNativeField(NAME_CeilingZ, TypeFloat64, myoffsetof(AActor, ceilingz), VARF_ReadOnly);
meta->AddNativeField(NAME_FloorZ, TypeFloat64, myoffsetof(AActor, floorz), VARF_ReadOnly);
meta->AddNativeField(NAME_Health, TypeSInt32, myoffsetof(AActor, health), VARF_ReadOnly);
meta->AddNativeField(NAME_Mass, TypeSInt32, myoffsetof(AActor, Mass));
meta->AddNativeField(NAME_Pitch, TypeFloat64, myoffsetof(AActor, Angles.Pitch));
meta->AddNativeField(NAME_Roll, TypeFloat64, myoffsetof(AActor, Angles.Roll));
meta->AddNativeField(NAME_Special, TypeSInt32, myoffsetof(AActor, special));
meta->AddNativeField(NAME_TID, TypeSInt32, myoffsetof(AActor, tid), VARF_ReadOnly);
meta->AddNativeField(NAME_TIDtoHate, TypeSInt32, myoffsetof(AActor, TIDtoHate), VARF_ReadOnly);
meta->AddNativeField(NAME_WaterLevel, TypeSInt32, myoffsetof(AActor, waterlevel), VARF_ReadOnly);
meta->AddNativeField(NAME_X, TypeFloat64, myoffsetof(AActor, __Pos.X), VARF_ReadOnly | VARF_Deprecated); // must remain read-only!
meta->AddNativeField(NAME_Y, TypeFloat64, myoffsetof(AActor, __Pos.Y), VARF_ReadOnly | VARF_Deprecated); // must remain read-only!
meta->AddNativeField(NAME_Z, TypeFloat64, myoffsetof(AActor, __Pos.Z), VARF_ReadOnly | VARF_Deprecated); // must remain read-only!
meta->AddNativeField(NAME_VelX, TypeFloat64, myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_VelY, TypeFloat64, myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_VelZ, TypeFloat64, myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_MomX, TypeFloat64, myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_MomY, TypeFloat64, myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_MomZ, TypeFloat64, myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated);
meta->AddNativeField(NAME_ScaleX, TypeFloat64, myoffsetof(AActor, Scale.X), VARF_Deprecated);
meta->AddNativeField(NAME_ScaleY, TypeFloat64, myoffsetof(AActor, Scale.Y), VARF_Deprecated);
meta->AddNativeField(NAME_Score, TypeSInt32, myoffsetof(AActor, Score));
meta->AddNativeField(NAME_Accuracy, TypeSInt32, myoffsetof(AActor, accuracy));
meta->AddNativeField(NAME_Stamina, TypeSInt32, myoffsetof(AActor, stamina));
meta->AddNativeField(NAME_Height, TypeFloat64, myoffsetof(AActor, Height));
meta->AddNativeField(NAME_Radius, TypeFloat64, myoffsetof(AActor, radius), VARF_ReadOnly);
meta->AddNativeField(NAME_ReactionTime, TypeSInt32, myoffsetof(AActor, reactiontime));
meta->AddNativeField(NAME_MeleeRange, TypeFloat64, myoffsetof(AActor, meleerange));
meta->AddNativeField(NAME_Speed, TypeFloat64, myoffsetof(AActor, Speed));
meta->AddNativeField("FloatSpeed", TypeFloat64, myoffsetof(AActor, FloatSpeed));
meta->AddNativeField("PainThreshold", TypeSInt32, myoffsetof(AActor, PainThreshold));
meta->AddNativeField("spriteAngle", TypeFloat64, myoffsetof(AActor, SpriteAngle));
meta->AddNativeField("spriteRotation", TypeFloat64, myoffsetof(AActor, SpriteRotation));
meta->AddNativeField(NAME_Threshold, TypeSInt32, myoffsetof(AActor, threshold));
meta->AddNativeField(NAME_DefThreshold, TypeSInt32, myoffsetof(AActor, DefThreshold), VARF_ReadOnly);
meta->AddNativeField(NAME_Damage, TypeSInt32, myoffsetof(AActor, DamageVal), VARF_ReadOnly);
meta->AddNativeField("visdir", TypeSInt32, myoffsetof(AActor, visdir));
meta->AddNativeField("Gravity", TypeFloat64, myoffsetof(AActor, Gravity));
meta->AddNativeField("FloorClip", TypeFloat64, myoffsetof(AActor, Floorclip));
meta->AddNativeField("DamageType", TypeName, myoffsetof(AActor, DamageType));
meta->AddNativeField("FloatBobPhase", TypeUInt8, myoffsetof(AActor, FloatBobPhase));
meta->AddNativeField("tics", TypeSInt32, myoffsetof(AActor, tics));
meta->AddNativeField("RipperLevel", TypeSInt32, myoffsetof(AActor, RipperLevel));
meta->AddNativeField("RipLevelMin", TypeSInt32, myoffsetof(AActor, RipLevelMin));
meta->AddNativeField("RipLevelMax", TypeSInt32, myoffsetof(AActor, RipLevelMax));
meta->AddNativeField("special2", TypeSInt32, myoffsetof(AActor, special2));
meta->AddNativeField(NAME_VisibleStartAngle, TypeFloat64, myoffsetof(AActor, VisibleStartAngle));
meta->AddNativeField(NAME_VisibleStartPitch, TypeFloat64, myoffsetof(AActor, VisibleStartPitch));
meta->AddNativeField(NAME_VisibleEndAngle, TypeFloat64, myoffsetof(AActor, VisibleEndAngle));
meta->AddNativeField(NAME_VisibleEndPitch, TypeFloat64, myoffsetof(AActor, VisibleEndPitch));
meta->AddNativeField("AttackSound", TypeSound, myoffsetof(AActor, AttackSound));
meta->AddNativeField("DeathSound", TypeSound, myoffsetof(AActor, DeathSound));
meta->AddNativeField("SeeSound", TypeSound, myoffsetof(AActor, SeeSound));
meta->AddNativeField("Pos", TypeVector3, myoffsetof(AActor, __Pos), VARF_ReadOnly);
meta->AddNativeField("Vel", TypeVector3, myoffsetof(AActor, Vel));
meta->AddNativeField("Scale", TypeVector2, myoffsetof(AActor, Scale));
meta->AddNativeField("CurState", TypeState, myoffsetof(AActor, state), VARF_ReadOnly); // has to be renamed on the script side because it clashes with the same named type.
meta->AddNativeField("SeeState", TypeState, myoffsetof(AActor, SeeState), VARF_ReadOnly);
meta->AddNativeField(NAME_Target, TypeActor, myoffsetof(AActor, target));
meta->AddNativeField(NAME_Master, TypeActor, myoffsetof(AActor, master));
meta->AddNativeField(NAME_Tracer, TypeActor, myoffsetof(AActor, tracer));
meta->AddNativeField("LastHeard", TypeActor, myoffsetof(AActor, LastHeard));
meta->AddNativeField("LastEnemy", TypeActor, myoffsetof(AActor, lastenemy));
meta->AddNativeField("Sector", TypeSector, myoffsetof(AActor, Sector));
// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
for (size_t i = 0; ActorFlagDefs[i].flagbit != 0xffffffff; i++)
{
meta->AddNativeField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].structoffset, ActorFlagDefs[i].varflags, ActorFlagDefs[i].flagbit);
}
for (size_t i = 0; InternalActorFlagDefs[i].flagbit != 0xffffffff; i++)
{
meta->AddNativeField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].structoffset, InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].flagbit);
}
}
//==========================================================================
//
// AActor :: Serialize
@ -6707,10 +6800,21 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2OffsetZ)
// DropItem handling
//
//----------------------------------------------------------------------------
IMPLEMENT_POINTY_CLASS(DDropItem)
IMPLEMENT_POINTY_CLASS_WITH_FIELDS(DDropItem)
DECLARE_POINTER(Next)
END_POINTERS
void DDropItem::InitNativeFields()
{
auto meta = RUNTIME_CLASS(DDropItem);
PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem));
meta->AddNativeField("Next", TypeDropItem, myoffsetof(DDropItem, Next), VARF_ReadOnly);
meta->AddNativeField("Name", TypeName, myoffsetof(DDropItem, Name), VARF_ReadOnly);
meta->AddNativeField("Probability", TypeSInt32, myoffsetof(DDropItem, Probability), VARF_ReadOnly);
meta->AddNativeField("Amount", TypeSInt32, myoffsetof(DDropItem, Amount));
}
void PrintMiscActorInfo(AActor *query)
{
if (query)

View File

@ -215,7 +215,6 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
//==========================================================================
void ParseScripts();
void ParseAllDecorate();
void G_InitLevelLocalsForScript();
void LoadActors ()
{
@ -224,7 +223,6 @@ void LoadActors ()
timer.Reset(); timer.Clock();
FScriptPosition::ResetErrorCounter();
G_InitLevelLocalsForScript();
InitThingdef();
FScriptPosition::StrictErrors = true;
ParseScripts();

View File

@ -62,7 +62,7 @@ static TArray<AFuncDesc> AFTable;
#define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 }
// internal flags. These do not get exposed to actor definitions but scripts need to be able to access them as variables.
static FFlagDef InternalActorFlagDefs[]=
FFlagDef InternalActorFlagDefs[]=
{
DEFINE_FLAG(MF, INCHASE, AActor, flags),
DEFINE_FLAG(MF, UNMORPHED, AActor, flags),
@ -91,10 +91,11 @@ static FFlagDef InternalActorFlagDefs[]=
DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6),
DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7),
DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7),
{ 0xffffffff }
};
static FFlagDef ActorFlagDefs[]=
FFlagDef ActorFlagDefs[]=
{
DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags),
DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags),
@ -328,6 +329,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags),
DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags),
DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags),
{ 0xffffffff }
};
// These won't be accessible through bitfield variables
@ -433,7 +435,7 @@ static FFlagDef PowerSpeedFlagDefs[] =
static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] =
{
{ &RUNTIME_CLASS_CASTLESS(AActor), ActorFlagDefs, countof(ActorFlagDefs) },
{ &RUNTIME_CLASS_CASTLESS(AActor), ActorFlagDefs, countof(ActorFlagDefs)-1 }, // -1 to account for the terminator
{ &RUNTIME_CLASS_CASTLESS(AActor), MoreFlagDefs, countof(MoreFlagDefs) },
{ &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs) },
{ &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs) },
@ -634,6 +636,7 @@ static int funccmp(const void * a, const void * b)
// Initialization
//
//==========================================================================
void G_InitLevelLocalsForScript();
void InitThingdef()
{
@ -679,101 +682,14 @@ void InitThingdef()
auto sptr = NewPointer(sstruct);
sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget));
// Define some member variables we feel like exposing to the user
PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols;
PType *array5 = NewArray(TypeSInt32, 5);
symt.AddSymbol(new PField("sector", sptr, VARF_Native, myoffsetof(AActor, Sector)));
symt.AddSymbol(new PField(NAME_Alpha, TypeFloat64, VARF_Native, myoffsetof(AActor, Alpha)));
symt.AddSymbol(new PField(NAME_Angle, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Yaw)));
symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor, args)));
symt.AddSymbol(new PField(NAME_CeilingZ, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, ceilingz)));
symt.AddSymbol(new PField(NAME_FloorZ, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, floorz)));
symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, health)));
symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor, Mass)));
symt.AddSymbol(new PField(NAME_Pitch, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Pitch)));
symt.AddSymbol(new PField(NAME_Roll, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Roll)));
symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor, special)));
symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, tid)));
symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, TIDtoHate)));
symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, waterlevel)));
symt.AddSymbol(new PField(NAME_X, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.X))); // must remain read-only!
symt.AddSymbol(new PField(NAME_Y, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.Y))); // must remain read-only!
symt.AddSymbol(new PField(NAME_Z, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.Z))); // must remain read-only!
symt.AddSymbol(new PField(NAME_VelX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.X)));
symt.AddSymbol(new PField(NAME_VelY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Y)));
symt.AddSymbol(new PField(NAME_VelZ, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Z)));
symt.AddSymbol(new PField(NAME_MomX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.X)));
symt.AddSymbol(new PField(NAME_MomY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Y)));
symt.AddSymbol(new PField(NAME_MomZ, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Z)));
symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.X)));
symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.Y)));
symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor, Score)));
symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor, accuracy)));
symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor, stamina)));
symt.AddSymbol(new PField(NAME_Height, TypeFloat64, VARF_Native, myoffsetof(AActor, Height)));
symt.AddSymbol(new PField(NAME_Radius, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, radius)));
symt.AddSymbol(new PField(NAME_ReactionTime, TypeSInt32, VARF_Native, myoffsetof(AActor, reactiontime)));
symt.AddSymbol(new PField(NAME_MeleeRange, TypeFloat64, VARF_Native, myoffsetof(AActor, meleerange)));
symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor, Speed)));
symt.AddSymbol(new PField("FloatSpeed", TypeFloat64, VARF_Native, myoffsetof(AActor, FloatSpeed)));
symt.AddSymbol(new PField("PainThreshold", TypeSInt32, VARF_Native, myoffsetof(AActor, PainThreshold)));
symt.AddSymbol(new PField("spriteAngle", TypeFloat64, VARF_Native, myoffsetof(AActor, SpriteAngle)));
symt.AddSymbol(new PField("spriteRotation", TypeFloat64, VARF_Native, myoffsetof(AActor, SpriteRotation)));
symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor, threshold)));
symt.AddSymbol(new PField(NAME_DefThreshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DefThreshold)));
symt.AddSymbol(new PField(NAME_Damage, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DamageVal)));
symt.AddSymbol(new PField("visdir", TypeSInt32, VARF_Native, myoffsetof(AActor, visdir)));
symt.AddSymbol(new PField("Gravity", TypeFloat64, VARF_Native, myoffsetof(AActor, Gravity)));
symt.AddSymbol(new PField("FloorClip", TypeFloat64, VARF_Native, myoffsetof(AActor, Floorclip)));
symt.AddSymbol(new PField("DamageType", TypeName, VARF_Native, myoffsetof(AActor, DamageType)));
symt.AddSymbol(new PField("FloatBobPhase", TypeUInt8, VARF_Native, myoffsetof(AActor, FloatBobPhase)));
symt.AddSymbol(new PField("tics", TypeSInt32, VARF_Native, myoffsetof(AActor, tics)));
symt.AddSymbol(new PField("RipperLevel", TypeSInt32, VARF_Native, myoffsetof(AActor, RipperLevel)));
symt.AddSymbol(new PField("RipLevelMin", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMin)));
symt.AddSymbol(new PField("RipLevelMax", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMax)));
symt.AddSymbol(new PField("special2", TypeSInt32, VARF_Native, myoffsetof(AActor, special2)));
symt.AddSymbol(new PField(NAME_VisibleStartAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartAngle)));
symt.AddSymbol(new PField(NAME_VisibleStartPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartPitch)));
symt.AddSymbol(new PField(NAME_VisibleEndAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndAngle)));
symt.AddSymbol(new PField(NAME_VisibleEndPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndPitch)));
symt.AddSymbol(new PField("AttackSound", TypeSound, VARF_Native, myoffsetof(AActor, AttackSound)));
symt.AddSymbol(new PField("DeathSound", TypeSound, VARF_Native, myoffsetof(AActor, DeathSound)));
symt.AddSymbol(new PField("SeeSound", TypeSound, VARF_Native, myoffsetof(AActor, SeeSound)));
symt.AddSymbol(new PField("Pos", TypeVector3, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, __Pos)));
symt.AddSymbol(new PField("Vel", TypeVector3, VARF_Native, myoffsetof(AActor, Vel)));
symt.AddSymbol(new PField("Scale", TypeVector2, VARF_Native, myoffsetof(AActor, Scale)));
symt.AddSymbol(new PField("CurState", TypeState, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, state))); // has to be renamed on the script side because it clashes with the same named type.
symt.AddSymbol(new PField("SeeState", TypeState, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, SeeState)));
symt.AddSymbol(new PField(NAME_Target, TypeActor, VARF_Native, myoffsetof(AActor, target)));
symt.AddSymbol(new PField(NAME_Master, TypeActor, VARF_Native, myoffsetof(AActor, master)));
symt.AddSymbol(new PField(NAME_Tracer, TypeActor, VARF_Native, myoffsetof(AActor, tracer)));
symt.AddSymbol(new PField("LastHeard", TypeActor, VARF_Native, myoffsetof(AActor, LastHeard)));
symt.AddSymbol(new PField("LastEnemy", TypeActor, VARF_Native, myoffsetof(AActor, lastenemy)));
G_InitLevelLocalsForScript();
// synthesize a symbol for each flag.
for (size_t i = 0; i < countof(ActorFlagDefs); i++)
FAutoSegIterator probe(CRegHead, CRegTail);
while (*++probe != NULL)
{
int bit = 0;
unsigned val = ActorFlagDefs[i].flagbit;
while ((val >>= 1)) bit++;
symt.AddSymbol(new PField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].varflags, ActorFlagDefs[i].structoffset, bit));
if (((ClassReg *)*probe)->InitNatives)
((ClassReg *)*probe)->InitNatives();
}
for (size_t i = 0; i < countof(InternalActorFlagDefs); i++)
{
int bit = 0;
unsigned val = InternalActorFlagDefs[i].flagbit;
while ((val >>= 1)) bit++;
symt.AddSymbol(new PField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].structoffset, bit));
}
PSymbolTable &symt2 = RUNTIME_CLASS(DDropItem)->Symbols;
PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem));
symt2.AddSymbol(new PField("Next", TypeDropItem, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Next)));
symt2.AddSymbol(new PField("Name", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name)));
symt2.AddSymbol(new PField("Probability", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Probability)));
symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native, myoffsetof(DDropItem, Amount)));
PSymbolTable &symt3 = RUNTIME_CLASS(DObject)->Symbols;
symt3.AddSymbol(new PField("bDestroyed", TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(DObject, ObjectFlags), 5/*OF_EuthanizeMe*/));
}