diff --git a/src/actor.h b/src/actor.h index df5ef3c175..833cd2c0ab 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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(); diff --git a/src/dobject.cpp b/src/dobject.cpp index beef73c89d..56d12787f4 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -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; diff --git a/src/dobject.h b/src/dobject.h index 91a80f9d07..ea0a44a85c 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -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; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 53eedc4568..631a7e6eee 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -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__ diff --git a/src/g_level.cpp b/src/g_level.cpp index 5b0c46fa2b..b13a39e20b 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -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); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index a6197e9a66..4024bc9f9f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -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); } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 08b6627679..cf0a033b31 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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) diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 38bf2bcf6c..8c42e8987d 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -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(); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 4d18a083bc..f628dec3c1 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -62,7 +62,7 @@ static TArray 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*/)); }