From 099b9970efbc00b511a4520e435ccfa29543e751 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Nov 2016 23:42:32 +0100 Subject: [PATCH] - added proper definitions for all exported native fields. - synthesize native fields for all declared flags, not just for AActor. --- src/actor.h | 2 - src/d_player.h | 1 - src/dobject.cpp | 17 +- src/dobject.h | 6 +- src/dobjtype.cpp | 2 +- src/g_shared/a_armor.cpp | 15 +- src/g_shared/a_pickups.h | 2 - src/g_shared/a_weapons.cpp | 80 +++++-- src/p_mobj.cpp | 35 +-- src/p_pspr.cpp | 48 ++-- src/p_pspr.h | 2 +- src/p_user.cpp | 224 +++++++++--------- src/scripting/thingdef_data.cpp | 57 +++-- src/scripting/vm/vm.h | 7 +- src/scripting/zscript/zcc-parse.lemon | 3 +- src/scripting/zscript/zcc_compile.cpp | 9 +- src/scripting/zscript/zcc_parser.h | 5 + wadsrc/static/zscript/base.txt | 6 +- wadsrc/static/zscript/constants.txt | 1 + wadsrc/static/zscript/doom/weaponchaingun.txt | 2 +- wadsrc/static/zscript/shared/botstuff.txt | 4 + wadsrc/static/zscript/shared/inventory.txt | 34 +++ wadsrc/static/zscript/shared/player.txt | 136 ++++++++++- 23 files changed, 452 insertions(+), 246 deletions(-) diff --git a/src/actor.h b/src/actor.h index d8bb1a897..83873adc5 100644 --- a/src/actor.h +++ b/src/actor.h @@ -565,7 +565,6 @@ class DDropItem : public DObject { DECLARE_CLASS(DDropItem, DObject) HAS_OBJECT_POINTERS - HAS_FIELDS public: DDropItem *Next; FName Name; @@ -579,7 +578,6 @@ 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/d_player.h b/src/d_player.h index d3f684137..d1678b619 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -100,7 +100,6 @@ FString GetPrintableDisplayName(PClassPlayerPawn *cls); class APlayerPawn : public AActor { DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn) - HAS_FIELDS HAS_OBJECT_POINTERS public: diff --git a/src/dobject.cpp b/src/dobject.cpp index ad575bebc..e3e37432b 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -64,12 +64,15 @@ ClassReg DObject::RegistrationInfo = &DVMObject::RegistrationInfo, // VMExport nullptr, // Pointers &DObject::InPlaceConstructor, // ConstructNative - &DObject::InitNativeFields, // InitNatives + nullptr, sizeof(DObject), // SizeOf CLASSREG_PClass, // MetaClassNum }; _DECLARE_TI(DObject) +// This bit is needed in the playsim - but give it a less crappy name. +DEFINE_FIELD_BIT(DObject,ObjectFlags, bDestroyed, OF_EuthanizeMe) + //========================================================================== // // @@ -347,18 +350,6 @@ 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 d858e577f..f728713e0 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -150,9 +150,6 @@ protected: \ #define HAS_OBJECT_POINTERS \ static const size_t PointerOffsets[]; -#define HAS_FIELDS \ - static void InitNativeFields(); - #if defined(_MSC_VER) # pragma section(".creg$u",read) # define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg * const cls::RegistrationInfoPtr = &cls::RegistrationInfo; @@ -187,7 +184,7 @@ protected: \ // Possible arguments for the IMPLEMENT_CLASS macro #define _X_POINTERS_true(cls) cls::PointerOffsets #define _X_POINTERS_false(cls) nullptr -#define _X_FIELDS_true(cls) cls::InitNativeFields +#define _X_FIELDS_true(cls) nullptr #define _X_FIELDS_false(cls) nullptr #define _X_CONSTRUCTOR_true(cls) #define _X_CONSTRUCTOR_false(cls) void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } @@ -445,7 +442,6 @@ 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 5afb8a578..11640ec94 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2515,7 +2515,7 @@ PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue else { // Just abort. Bit fields should only be defined internally. - I_FatalError("Trying to create an invalid bit field element: %s", name.GetChars()); + I_Error("Trying to create an invalid bit field element: %s", name.GetChars()); } } else BitValue = -1; diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index c05cc2c6a..8f1116a9e 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -281,16 +281,17 @@ bool ABasicArmorPickup::Use (bool pickup) //=========================================================================== // -// ABasicArmorBonus :: InitNativeFields +// ABasicArmorBonus // //=========================================================================== -void ABasicArmorBonus::InitNativeFields() -{ - auto meta = RUNTIME_CLASS(ABasicArmorBonus); - meta->AddNativeField("SaveAmount", TypeSInt32, myoffsetof(ABasicArmorBonus, SaveAmount)); - meta->AddNativeField("MaxSaveAmount", TypeSInt32, myoffsetof(ABasicArmorBonus, MaxSaveAmount)); -} +DEFINE_FIELD(ABasicArmorBonus, SavePercent) +DEFINE_FIELD(ABasicArmorBonus, MaxSaveAmount) +DEFINE_FIELD(ABasicArmorBonus, MaxAbsorb) +DEFINE_FIELD(ABasicArmorBonus, MaxFullAbsorb) +DEFINE_FIELD(ABasicArmorBonus, SaveAmount) +DEFINE_FIELD(ABasicArmorBonus, BonusCount) +DEFINE_FIELD(ABasicArmorBonus, BonusMax) //=========================================================================== // diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 9e1caaf5b..6dc2d0bc5 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -289,7 +289,6 @@ public: class AWeapon : public AStateProvider { DECLARE_CLASS_WITH_META(AWeapon, AStateProvider, PClassWeapon) - HAS_FIELDS HAS_OBJECT_POINTERS public: DWORD WeaponFlags; @@ -500,7 +499,6 @@ public: class ABasicArmorBonus : public AArmor { DECLARE_CLASS (ABasicArmorBonus, AArmor) - HAS_FIELDS public: virtual void Serialize(FSerializer &arc); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 9af5c6de2..5f221c5bc 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -31,25 +31,45 @@ IMPLEMENT_POINTERS_START(AWeapon) IMPLEMENT_POINTER(SisterWeapon) IMPLEMENT_POINTERS_END -void AWeapon::InitNativeFields() -{ - auto meta = RUNTIME_CLASS(AWeapon); +DEFINE_FIELD(AWeapon, WeaponFlags) +DEFINE_FIELD(AWeapon, AmmoType1) +DEFINE_FIELD(AWeapon, AmmoType2) +DEFINE_FIELD(AWeapon, AmmoGive1) +DEFINE_FIELD(AWeapon, AmmoGive2) +DEFINE_FIELD(AWeapon, MinAmmo1) +DEFINE_FIELD(AWeapon, MinAmmo2) +DEFINE_FIELD(AWeapon, AmmoUse1) +DEFINE_FIELD(AWeapon, AmmoUse2) +DEFINE_FIELD(AWeapon, Kickback) +DEFINE_FIELD(AWeapon, YAdjust) +DEFINE_FIELD(AWeapon, UpSound) +DEFINE_FIELD(AWeapon, ReadySound) +DEFINE_FIELD(AWeapon, SisterWeaponType) +DEFINE_FIELD(AWeapon, ProjectileType) +DEFINE_FIELD(AWeapon, AltProjectileType) +DEFINE_FIELD(AWeapon, SelectionOrder) +DEFINE_FIELD(AWeapon, MinSelAmmo1) +DEFINE_FIELD(AWeapon, MinSelAmmo2) +DEFINE_FIELD(AWeapon, MoveCombatDist) +DEFINE_FIELD(AWeapon, ReloadCounter) +DEFINE_FIELD(AWeapon, BobStyle) +DEFINE_FIELD(AWeapon, BobSpeed) +DEFINE_FIELD(AWeapon, BobRangeX) +DEFINE_FIELD(AWeapon, BobRangeY) +DEFINE_FIELD(AWeapon, Ammo1) +DEFINE_FIELD(AWeapon, Ammo2) +DEFINE_FIELD(AWeapon, SisterWeapon) +DEFINE_FIELD(AWeapon, FOVScale) +DEFINE_FIELD(AWeapon, Crosshair) +DEFINE_FIELD(AWeapon, GivenAsMorphWeapon) +DEFINE_FIELD(AWeapon, bAltFire) +DEFINE_FIELD_BIT(AWeapon, WeaponFlags, bDehAmmo, WIF_DEHAMMO) - meta->AddNativeField("bAltFire", TypeBool, myoffsetof(AWeapon, bAltFire)); - - - // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. - for (size_t i = 0; WeaponFlagDefs[i].flagbit != 0xffffffff; i++) - { - if (WeaponFlagDefs[i].structoffset > 0) - { - meta->AddNativeField(FStringf("b%s", WeaponFlagDefs[i].name), (WeaponFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), WeaponFlagDefs[i].structoffset, WeaponFlagDefs[i].varflags, WeaponFlagDefs[i].flagbit); - } - } - // This flag is not accessible through actor definitions. - meta->AddNativeField("bDehAmmo", TypeSInt32, myoffsetof(AWeapon, WeaponFlags), VARF_ReadOnly, WIF_DEHAMMO); - -} +//=========================================================================== +// +// +// +//=========================================================================== FString WeaponSection; TArray KeyConfWeapons; @@ -62,12 +82,24 @@ static int ntoh_cmp(const void *a, const void *b); IMPLEMENT_CLASS(PClassWeapon, false, false, false, false) +//=========================================================================== +// +// +// +//=========================================================================== + PClassWeapon::PClassWeapon() { SlotNumber = -1; SlotPriority = INT_MAX; } +//=========================================================================== +// +// +// +//=========================================================================== + void PClassWeapon::DeriveData(PClass *newclass) { assert(newclass->IsKindOf(RUNTIME_CLASS(PClassWeapon))); @@ -79,6 +111,12 @@ void PClassWeapon::DeriveData(PClass *newclass) } +//=========================================================================== +// +// +// +//=========================================================================== + void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass) { Super::ReplaceClassRef(oldclass, newclass); @@ -91,6 +129,12 @@ void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass) } } +//=========================================================================== +// +// +// +//=========================================================================== + void PClassWeapon::Finalize(FStateDefinitions &statedef) { Super::Finalize(statedef); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 181399655..29123590a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -131,7 +131,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE); // CODE -------------------------------------------------------------------- -IMPLEMENT_CLASS(AActor, false, true, true, true) +IMPLEMENT_CLASS(AActor, false, true, false, true) IMPLEMENT_POINTERS_START(AActor) IMPLEMENT_POINTER(target) @@ -310,24 +310,6 @@ DEFINE_FIELD(AActor, ConversationRoot) DEFINE_FIELD(AActor, Conversation) DEFINE_FIELD(AActor, DecalGenerator) - -void AActor::InitNativeFields() -{ - auto meta = RUNTIME_CLASS(AActor); - // needs to be done manually until it can be given a proper type. - meta->AddNativeField("DecalGenerator", NewPointer(TypeVoid), myoffsetof(AActor, DecalGenerator)); - - // 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 @@ -7183,18 +7165,13 @@ DEFINE_ACTION_FUNCTION(AActor, Vec3Offset) IMPLEMENT_CLASS(DDropItem, false, true, true, false) IMPLEMENT_POINTERS_START(DDropItem) - IMPLEMENT_POINTER(Next) +IMPLEMENT_POINTER(Next) IMPLEMENT_POINTERS_END -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)); -} +DEFINE_FIELD(DDropItem, Next) +DEFINE_FIELD(DDropItem, Name) +DEFINE_FIELD(DDropItem, Probability) +DEFINE_FIELD(DDropItem, Amount) void PrintMiscActorInfo(AActor *query) { diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index f1cc8e792..0e39e259e 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -99,40 +99,32 @@ static const FGenericButtons ButtonChecks[] = // //------------------------------------------------------------------------ -IMPLEMENT_CLASS(DPSprite, false, true, true, false) +IMPLEMENT_CLASS(DPSprite, false, true, false, false) IMPLEMENT_POINTERS_START(DPSprite) IMPLEMENT_POINTER(Caller) IMPLEMENT_POINTER(Next) IMPLEMENT_POINTERS_END -void DPSprite::InitNativeFields() -{ - auto meta = RUNTIME_CLASS(DPSprite); - PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor)); - PType *TypePSP = NewPointer(RUNTIME_CLASS(DPSprite)); - PType *TypePlayer = NewPointer(NewNativeStruct("Player", nullptr)); - - meta->AddNativeField("State", TypeState, myoffsetof(DPSprite, State), VARF_ReadOnly); - meta->AddNativeField("Caller", TypeActor, myoffsetof(DPSprite, Caller), VARF_ReadOnly); - meta->AddNativeField("Next", TypePSP, myoffsetof(DPSprite, Next), VARF_ReadOnly); - meta->AddNativeField("Owner", TypePlayer, myoffsetof(DPSprite, Owner), VARF_ReadOnly); - meta->AddNativeField("Sprite", TypeSpriteID, myoffsetof(DPSprite, Sprite)); - meta->AddNativeField("Frame", TypeSInt32, myoffsetof(DPSprite, Frame)); - meta->AddNativeField("ID", TypePlayer, myoffsetof(DPSprite, ID), VARF_ReadOnly); - meta->AddNativeField("processPending", TypeBool, myoffsetof(DPSprite, processPending)); - meta->AddNativeField("x", TypeFloat64, myoffsetof(DPSprite, x)); - meta->AddNativeField("y", TypeFloat64, myoffsetof(DPSprite, y)); - meta->AddNativeField("oldx", TypeFloat64, myoffsetof(DPSprite, oldx)); - meta->AddNativeField("oldy", TypeFloat64, myoffsetof(DPSprite, oldy)); - meta->AddNativeField("firstTic", TypeBool, myoffsetof(DPSprite, firstTic)); - meta->AddNativeField("Tics", TypeSInt32, myoffsetof(DPSprite, Tics)); - meta->AddNativeField("bAddWeapon", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_ADDWEAPON); - meta->AddNativeField("bAddBob", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_ADDBOB); - meta->AddNativeField("bPowDouble", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_POWDOUBLE); - meta->AddNativeField("bCVarFast", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_CVARFAST); - meta->AddNativeField("bFlip", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_FLIP); -} +DEFINE_FIELD_NAMED(DPSprite, State, CurState) // deconflict with same named type +DEFINE_FIELD(DPSprite, Caller) +DEFINE_FIELD(DPSprite, Next) +DEFINE_FIELD(DPSprite, Owner) +DEFINE_FIELD(DPSprite, Sprite) +DEFINE_FIELD(DPSprite, Frame) +DEFINE_FIELD(DPSprite, ID) +DEFINE_FIELD(DPSprite, processPending) +DEFINE_FIELD(DPSprite, x) +DEFINE_FIELD(DPSprite, y) +DEFINE_FIELD(DPSprite, oldx) +DEFINE_FIELD(DPSprite, oldy) +DEFINE_FIELD(DPSprite, firstTic) +DEFINE_FIELD(DPSprite, Tics) +DEFINE_FIELD_BIT(DPSprite, Flags, bAddWeapon, PSPF_ADDWEAPON) +DEFINE_FIELD_BIT(DPSprite, Flags, bAddBob, PSPF_ADDBOB) +DEFINE_FIELD_BIT(DPSprite, Flags, bPowDouble, PSPF_POWDOUBLE) +DEFINE_FIELD_BIT(DPSprite, Flags, bCVarFast, PSPF_CVARFAST) +DEFINE_FIELD_BIT(DPSprite, Flags, bFlip, PSPF_FLIP) //------------------------------------------------------------------------ // diff --git a/src/p_pspr.h b/src/p_pspr.h index 4c019c7d4..7039b2cc8 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -59,7 +59,6 @@ enum PSPFlags class DPSprite : public DObject { DECLARE_CLASS (DPSprite, DObject) - HAS_FIELDS HAS_OBJECT_POINTERS public: DPSprite(player_t *owner, AActor *caller, int id); @@ -89,6 +88,7 @@ private: void Tick(); void Destroy(); +public: // must be public to be able to generate the field export tables. Grrr... TObjPtr Caller; TObjPtr Next; player_t *Owner; diff --git a/src/p_user.cpp b/src/p_user.cpp index 5b25fd713..2917db668 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -161,12 +161,6 @@ bool ValidatePlayerClass(PClassActor *ti, const char *name) return true; } -void APlayerPawn::InitNativeFields() -{ - auto meta = RUNTIME_CLASS(APlayerPawn); - meta->AddNativeField("JumpZ", TypeFloat64, myoffsetof(APlayerPawn, JumpZ)); -} - void SetupPlayerClasses () { FPlayerClass newclass; @@ -628,7 +622,7 @@ void player_t::SendPitchLimits() const // //=========================================================================== -IMPLEMENT_CLASS(APlayerPawn, false, true, true, true) +IMPLEMENT_CLASS(APlayerPawn, false, true, false, true) IMPLEMENT_POINTERS_START(APlayerPawn) IMPLEMENT_POINTER(InvFirst) @@ -3139,112 +3133,118 @@ bool P_IsPlayerTotallyFrozen(const player_t *player) //========================================================================== // -// sets up the script-side version of players -// Since this is a global variable and the script compiler does -// not allow defining them, it will be fully set up here. +// native members // //========================================================================== -void P_InitPlayerForScript() -{ - PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr); - pstruct->Size = sizeof(player_t); - pstruct->Align = alignof(player_t); - PArray *parray = NewArray(pstruct, MAXPLAYERS); - pstruct->Size = 0; // make sure it cannot be instantiated in the script. - PField *playerf = new PField("players", pstruct, VARF_Native | VARF_Static, (intptr_t)&players); - GlobalSymbols.AddSymbol(playerf); +DEFINE_FIELD(APlayerPawn, crouchsprite) +DEFINE_FIELD(APlayerPawn, MaxHealth) +DEFINE_FIELD(APlayerPawn, MugShotMaxHealth) +DEFINE_FIELD(APlayerPawn, RunHealth) +DEFINE_FIELD(APlayerPawn, PlayerFlags) +DEFINE_FIELD(APlayerPawn, InvFirst) +DEFINE_FIELD(APlayerPawn, InvSel) +DEFINE_FIELD(APlayerPawn, JumpZ) +DEFINE_FIELD(APlayerPawn, GruntSpeed) +DEFINE_FIELD(APlayerPawn, FallingScreamMinSpeed) +DEFINE_FIELD(APlayerPawn, FallingScreamMaxSpeed) +DEFINE_FIELD(APlayerPawn, ViewHeight) +DEFINE_FIELD(APlayerPawn, ForwardMove1) +DEFINE_FIELD(APlayerPawn, ForwardMove2) +DEFINE_FIELD(APlayerPawn, SideMove1) +DEFINE_FIELD(APlayerPawn, SideMove2) +DEFINE_FIELD(APlayerPawn, ScoreIcon) +DEFINE_FIELD(APlayerPawn, SpawnMask) +DEFINE_FIELD(APlayerPawn, MorphWeapon) +DEFINE_FIELD(APlayerPawn, AttackZOffset) +DEFINE_FIELD(APlayerPawn, UseRange) +DEFINE_FIELD(APlayerPawn, AirCapacity) +DEFINE_FIELD(APlayerPawn, FlechetteType) +DEFINE_FIELD(APlayerPawn, DamageFade) +DEFINE_FIELD(APlayerPawn, ViewBob) - PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor)); - PType *TypePlayerPawn = NewPointer(RUNTIME_CLASS(APlayerPawn)); - PType *TypeWeapon = NewPointer(RUNTIME_CLASS(AWeapon)); - PType *TypeClassActor = NewClassPointer(RUNTIME_CLASS(AActor)); - PType *TypeClassPlayerPawn = NewClassPointer(RUNTIME_CLASS(APlayerPawn)); - PType *TypeClassWeapon = NewClassPointer(RUNTIME_CLASS(AWeapon)); - - //ticcmd_t cmd; - //usercmd_t original_cmd; - //userinfo_t userinfo; // [RH] who is this? - //FWeaponSlots weapons; - pstruct->AddNativeField("mo", TypePlayerPawn, myoffsetof(player_t, mo), VARF_ReadOnly); - pstruct->AddNativeField("playerstate", TypeUInt8, myoffsetof(player_t, playerstate)); - pstruct->AddNativeField("original_oldbuttons", TypeUInt32, myoffsetof(player_t, original_oldbuttons)); - pstruct->AddNativeField("cls", TypeClassPlayerPawn, myoffsetof(player_t, cls), VARF_ReadOnly); - pstruct->AddNativeField("DesiredFOV", TypeFloat32, myoffsetof(player_t, DesiredFOV)); - pstruct->AddNativeField("FOV", TypeFloat32, myoffsetof(player_t, FOV), VARF_ReadOnly); - pstruct->AddNativeField("viewz", TypeFloat64, myoffsetof(player_t, viewz)); - pstruct->AddNativeField("viewheight", TypeFloat64, myoffsetof(player_t, viewheight)); - pstruct->AddNativeField("deltaviewheight", TypeFloat64, myoffsetof(player_t, deltaviewheight)); - pstruct->AddNativeField("bob", TypeFloat64, myoffsetof(player_t, bob)); - pstruct->AddNativeField("vel", TypeVector2, myoffsetof(player_t, Vel)); - pstruct->AddNativeField("centering", TypeBool, myoffsetof(player_t, centering)); - pstruct->AddNativeField("turnticks", TypeUInt8, myoffsetof(player_t, turnticks)); - pstruct->AddNativeField("attackdown", TypeBool, myoffsetof(player_t, attackdown)); - pstruct->AddNativeField("usedown", TypeBool, myoffsetof(player_t, usedown)); - pstruct->AddNativeField("oldbuttons", TypeUInt32, myoffsetof(player_t, oldbuttons)); - pstruct->AddNativeField("health", TypeSInt32, myoffsetof(player_t, health)); - pstruct->AddNativeField("inventorytics", TypeSInt32, myoffsetof(player_t, inventorytics)); - pstruct->AddNativeField("CurrentPlayerClass", TypeUInt8, myoffsetof(player_t, CurrentPlayerClass)); - pstruct->AddNativeField("frags", NewArray(TypeSInt32, MAXPLAYERS), myoffsetof(player_t, frags)); - pstruct->AddNativeField("fragcount", TypeSInt32, myoffsetof(player_t, fragcount)); - pstruct->AddNativeField("lastkilltime", TypeSInt32, myoffsetof(player_t, lastkilltime)); - pstruct->AddNativeField("multicount", TypeUInt8, myoffsetof(player_t, multicount)); - pstruct->AddNativeField("spreecount", TypeUInt8, myoffsetof(player_t, spreecount)); - pstruct->AddNativeField("WeaponState", TypeUInt16, myoffsetof(player_t, WeaponState)); - pstruct->AddNativeField("ReadyWeapon", TypeWeapon, myoffsetof(player_t, ReadyWeapon)); - pstruct->AddNativeField("PendingWeapon", TypeWeapon, myoffsetof(player_t, PendingWeapon)); - pstruct->AddNativeField("psprites", NewPointer(RUNTIME_CLASS(DPSprite)), myoffsetof(player_t, psprites)); - pstruct->AddNativeField("cheats", TypeSInt32, myoffsetof(player_t, cheats)); - pstruct->AddNativeField("timefreezer", TypeSInt32, myoffsetof(player_t, timefreezer)); - pstruct->AddNativeField("refire", TypeSInt16, myoffsetof(player_t, refire)); - pstruct->AddNativeField("inconsistent", TypeSInt16, myoffsetof(player_t, inconsistant)); - pstruct->AddNativeField("waiting", TypeSInt32, myoffsetof(player_t, waiting)); - pstruct->AddNativeField("killcount", TypeSInt32, myoffsetof(player_t, killcount)); - pstruct->AddNativeField("itemcount", TypeSInt32, myoffsetof(player_t, itemcount)); - pstruct->AddNativeField("secretcount", TypeSInt32, myoffsetof(player_t, secretcount)); - pstruct->AddNativeField("damagecount", TypeSInt32, myoffsetof(player_t, damagecount)); - pstruct->AddNativeField("bonuscount", TypeSInt32, myoffsetof(player_t, bonuscount)); - pstruct->AddNativeField("hazardcount", TypeSInt32, myoffsetof(player_t, hazardcount)); - pstruct->AddNativeField("hazardinterval", TypeSInt32, myoffsetof(player_t, hazardinterval)); - pstruct->AddNativeField("hazardtype", TypeName, myoffsetof(player_t, hazardtype)); - pstruct->AddNativeField("poisoncount", TypeSInt32, myoffsetof(player_t, poisoncount)); - pstruct->AddNativeField("poisontype", TypeName, myoffsetof(player_t, poisontype)); - pstruct->AddNativeField("poisonpaintype", TypeName, myoffsetof(player_t, poisonpaintype)); - pstruct->AddNativeField("poisoner", TypeActor, myoffsetof(player_t, poisoner)); - pstruct->AddNativeField("attacker", TypeActor, myoffsetof(player_t, attacker)); - pstruct->AddNativeField("extralight", TypeSInt32, myoffsetof(player_t, extralight)); - pstruct->AddNativeField("fixedcolormap", TypeSInt16, myoffsetof(player_t, fixedcolormap)); - pstruct->AddNativeField("fixedlightlevel", TypeSInt16, myoffsetof(player_t, fixedlightlevel)); - pstruct->AddNativeField("morphtics", TypeSInt32, myoffsetof(player_t, morphTics)); - pstruct->AddNativeField("MorphedPlayerClass", TypeClassPlayerPawn, myoffsetof(player_t, MorphedPlayerClass)); - pstruct->AddNativeField("MorphStyle", TypeSInt32, myoffsetof(player_t, MorphStyle)); - pstruct->AddNativeField("MorphExitFlash", TypeClassActor, myoffsetof(player_t, MorphExitFlash)); - pstruct->AddNativeField("PremorphWeapon", TypeClassWeapon, myoffsetof(player_t, PremorphWeapon)); - pstruct->AddNativeField("chickenPeck", TypeSInt32, myoffsetof(player_t, chickenPeck)); - pstruct->AddNativeField("jumpTics", TypeSInt32, myoffsetof(player_t, jumpTics)); - pstruct->AddNativeField("onground", TypeBool, myoffsetof(player_t, onground)); - pstruct->AddNativeField("respawn_time", TypeSInt32, myoffsetof(player_t, respawn_time)); - pstruct->AddNativeField("camera", TypeActor, myoffsetof(player_t, camera)); - pstruct->AddNativeField("air_finished", TypeSInt32, myoffsetof(player_t, air_finished)); - pstruct->AddNativeField("LastDamageType", TypeName, myoffsetof(player_t, LastDamageType)); - pstruct->AddNativeField("MUSINFOactor", TypeActor, myoffsetof(player_t, MUSINFOactor)); - pstruct->AddNativeField("MUSINFOtics", TypeSInt8, myoffsetof(player_t, MUSINFOtics)); - pstruct->AddNativeField("settings_controller", TypeBool, myoffsetof(player_t, settings_controller)); - pstruct->AddNativeField("crouching", TypeSInt8, myoffsetof(player_t, crouching)); - pstruct->AddNativeField("crouchdir", TypeSInt8, myoffsetof(player_t, crouchdir)); - pstruct->AddNativeField("bot", NewPointer(RUNTIME_CLASS(DBot)), myoffsetof(player_t, Bot)); - pstruct->AddNativeField("BlendR", TypeFloat32, myoffsetof(player_t, BlendR)); - pstruct->AddNativeField("BlendG", TypeFloat32, myoffsetof(player_t, BlendG)); - pstruct->AddNativeField("BlendB", TypeFloat32, myoffsetof(player_t, BlendB)); - pstruct->AddNativeField("BlendA", TypeFloat32, myoffsetof(player_t, BlendA)); - pstruct->AddNativeField("LogText", TypeString, myoffsetof(player_t, LogText)); - pstruct->AddNativeField("MinPitch", TypeFloat64, myoffsetof(player_t, MinPitch)); - pstruct->AddNativeField("MaxPitch", TypeFloat64, myoffsetof(player_t, MaxPitch)); - pstruct->AddNativeField("crouchfactor", TypeFloat64, myoffsetof(player_t, crouchfactor)); - pstruct->AddNativeField("crouchoffset", TypeFloat64, myoffsetof(player_t, crouchoffset)); - pstruct->AddNativeField("crouchviewdelta", TypeFloat64, myoffsetof(player_t, crouchviewdelta)); - pstruct->AddNativeField("ConversationNPC", TypeActor, myoffsetof(player_t, ConversationNPC)); - pstruct->AddNativeField("ConversationPC", TypeActor, myoffsetof(player_t, ConversationPC)); - pstruct->AddNativeField("ConversationNPCAngle", TypeFloat64, myoffsetof(player_t, ConversationNPCAngle)); - pstruct->AddNativeField("ConversationFaceTalker", TypeBool, myoffsetof(player_t, ConversationFaceTalker)); -} \ No newline at end of file +DEFINE_FIELD_X(PlayerInfo, player_t, mo) +DEFINE_FIELD_X(PlayerInfo, player_t, playerstate) +DEFINE_FIELD_X(PlayerInfo, player_t, original_oldbuttons) +DEFINE_FIELD_X(PlayerInfo, player_t, cls) +DEFINE_FIELD_X(PlayerInfo, player_t, DesiredFOV) +DEFINE_FIELD_X(PlayerInfo, player_t, FOV) +DEFINE_FIELD_X(PlayerInfo, player_t, viewz) +DEFINE_FIELD_X(PlayerInfo, player_t, viewheight) +DEFINE_FIELD_X(PlayerInfo, player_t, deltaviewheight) +DEFINE_FIELD_X(PlayerInfo, player_t, bob) +DEFINE_FIELD_X(PlayerInfo, player_t, Vel) +DEFINE_FIELD_X(PlayerInfo, player_t, centering) +DEFINE_FIELD_X(PlayerInfo, player_t, turnticks) +DEFINE_FIELD_X(PlayerInfo, player_t, attackdown) +DEFINE_FIELD_X(PlayerInfo, player_t, usedown) +DEFINE_FIELD_X(PlayerInfo, player_t, oldbuttons) +DEFINE_FIELD_X(PlayerInfo, player_t, health) +DEFINE_FIELD_X(PlayerInfo, player_t, inventorytics) +DEFINE_FIELD_X(PlayerInfo, player_t, CurrentPlayerClass) +DEFINE_FIELD_X(PlayerInfo, player_t, frags) +DEFINE_FIELD_X(PlayerInfo, player_t, fragcount) +DEFINE_FIELD_X(PlayerInfo, player_t, lastkilltime) +DEFINE_FIELD_X(PlayerInfo, player_t, multicount) +DEFINE_FIELD_X(PlayerInfo, player_t, spreecount) +DEFINE_FIELD_X(PlayerInfo, player_t, WeaponState) +DEFINE_FIELD_X(PlayerInfo, player_t, ReadyWeapon) +DEFINE_FIELD_X(PlayerInfo, player_t, PendingWeapon) +DEFINE_FIELD_X(PlayerInfo, player_t, psprites) +DEFINE_FIELD_X(PlayerInfo, player_t, cheats) +DEFINE_FIELD_X(PlayerInfo, player_t, timefreezer) +DEFINE_FIELD_X(PlayerInfo, player_t, refire) +DEFINE_FIELD_NAMED_X(PlayerInfo, player_t, inconsistant, inconsistent) +DEFINE_FIELD_X(PlayerInfo, player_t, waiting) +DEFINE_FIELD_X(PlayerInfo, player_t, killcount) +DEFINE_FIELD_X(PlayerInfo, player_t, itemcount) +DEFINE_FIELD_X(PlayerInfo, player_t, secretcount) +DEFINE_FIELD_X(PlayerInfo, player_t, damagecount) +DEFINE_FIELD_X(PlayerInfo, player_t, bonuscount) +DEFINE_FIELD_X(PlayerInfo, player_t, hazardcount) +DEFINE_FIELD_X(PlayerInfo, player_t, hazardinterval) +DEFINE_FIELD_X(PlayerInfo, player_t, hazardtype) +DEFINE_FIELD_X(PlayerInfo, player_t, poisoncount) +DEFINE_FIELD_X(PlayerInfo, player_t, poisontype) +DEFINE_FIELD_X(PlayerInfo, player_t, poisonpaintype) +DEFINE_FIELD_X(PlayerInfo, player_t, poisoner) +DEFINE_FIELD_X(PlayerInfo, player_t, attacker) +DEFINE_FIELD_X(PlayerInfo, player_t, extralight) +DEFINE_FIELD_X(PlayerInfo, player_t, fixedcolormap) +DEFINE_FIELD_X(PlayerInfo, player_t, fixedlightlevel) +DEFINE_FIELD_X(PlayerInfo, player_t, morphTics) +DEFINE_FIELD_X(PlayerInfo, player_t, MorphedPlayerClass) +DEFINE_FIELD_X(PlayerInfo, player_t, MorphStyle) +DEFINE_FIELD_X(PlayerInfo, player_t, MorphExitFlash) +DEFINE_FIELD_X(PlayerInfo, player_t, PremorphWeapon) +DEFINE_FIELD_X(PlayerInfo, player_t, chickenPeck) +DEFINE_FIELD_X(PlayerInfo, player_t, jumpTics) +DEFINE_FIELD_X(PlayerInfo, player_t, onground) +DEFINE_FIELD_X(PlayerInfo, player_t, respawn_time) +DEFINE_FIELD_X(PlayerInfo, player_t, camera) +DEFINE_FIELD_X(PlayerInfo, player_t, air_finished) +DEFINE_FIELD_X(PlayerInfo, player_t, LastDamageType) +DEFINE_FIELD_X(PlayerInfo, player_t, MUSINFOactor) +DEFINE_FIELD_X(PlayerInfo, player_t, MUSINFOtics) +DEFINE_FIELD_X(PlayerInfo, player_t, settings_controller) +DEFINE_FIELD_X(PlayerInfo, player_t, crouching) +DEFINE_FIELD_X(PlayerInfo, player_t, crouchdir) +DEFINE_FIELD_X(PlayerInfo, player_t, Bot) +DEFINE_FIELD_X(PlayerInfo, player_t, BlendR) +DEFINE_FIELD_X(PlayerInfo, player_t, BlendG) +DEFINE_FIELD_X(PlayerInfo, player_t, BlendB) +DEFINE_FIELD_X(PlayerInfo, player_t, BlendA) +DEFINE_FIELD_X(PlayerInfo, player_t, LogText) +DEFINE_FIELD_X(PlayerInfo, player_t, MinPitch) +DEFINE_FIELD_X(PlayerInfo, player_t, MaxPitch) +DEFINE_FIELD_X(PlayerInfo, player_t, crouchfactor) +DEFINE_FIELD_X(PlayerInfo, player_t, crouchoffset) +DEFINE_FIELD_X(PlayerInfo, player_t, crouchviewdelta) +DEFINE_FIELD_X(PlayerInfo, player_t, ConversationNPC) +DEFINE_FIELD_X(PlayerInfo, player_t, ConversationPC) +DEFINE_FIELD_X(PlayerInfo, player_t, ConversationNPCAngle) +DEFINE_FIELD_X(PlayerInfo, player_t, ConversationFaceTalker) +DEFINE_FIELD_X(PlayerInfo, player_t, cmd) +DEFINE_FIELD_X(PlayerInfo, player_t, original_cmd) +DEFINE_FIELD_X(PlayerInfo, player_t, userinfo) +DEFINE_FIELD_X(PlayerInfo, player_t, weapons) diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index d50f73bd3..7488c9716 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -63,7 +63,7 @@ static TArray FieldTable; #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. -FFlagDef InternalActorFlagDefs[]= +static FFlagDef InternalActorFlagDefs[]= { DEFINE_FLAG(MF, INCHASE, AActor, flags), DEFINE_FLAG(MF, UNMORPHED, AActor, flags), @@ -90,11 +90,10 @@ FFlagDef InternalActorFlagDefs[]= DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6), DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7), DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7), - { 0xffffffff } }; -FFlagDef ActorFlagDefs[]= +static FFlagDef ActorFlagDefs[]= { DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags), DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags), @@ -328,7 +327,6 @@ 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 @@ -387,10 +385,9 @@ static FFlagDef InventoryFlagDefs[] = DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP), - { 0xffffffff } }; -FFlagDef WeaponFlagDefs[] = +static FFlagDef WeaponFlagDefs[] = { // Weapon flags DEFINE_FLAG(WIF, NOAUTOFIRE, AWeapon, WeaponFlags), @@ -417,7 +414,6 @@ FFlagDef WeaponFlagDefs[] = DEFINE_DUMMY_FLAG(NOLMS, false), DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL, false), - { 0xffffffff } }; @@ -428,24 +424,23 @@ static FFlagDef PlayerPawnFlagDefs[] = DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags), DEFINE_FLAG(PPF, CANSUPERMORPH, APlayerPawn, PlayerFlags), DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags), - { 0xffffffff } }; static FFlagDef PowerSpeedFlagDefs[] = { // PowerSpeed flags DEFINE_FLAG(PSF, NOTRAIL, APowerSpeed, SpeedFlags), - { 0xffffffff } }; -static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] = +static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; int Use; } FlagLists[] = { - { &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)-1 }, - { &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs)-1 }, - { &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs)-1 }, - { &RUNTIME_CLASS_CASTLESS(APowerSpeed), PowerSpeedFlagDefs, countof(PowerSpeedFlagDefs)-1 }, + { &RUNTIME_CLASS_CASTLESS(AActor), ActorFlagDefs, countof(ActorFlagDefs), 3 }, // -1 to account for the terminator + { &RUNTIME_CLASS_CASTLESS(AActor), MoreFlagDefs, countof(MoreFlagDefs), 1 }, + { &RUNTIME_CLASS_CASTLESS(AActor), InternalActorFlagDefs, countof(InternalActorFlagDefs), 2 }, + { &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs), 3 }, + { &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs), 3 }, + { &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs), 3 }, + { &RUNTIME_CLASS_CASTLESS(APowerSpeed), PowerSpeedFlagDefs, countof(PowerSpeedFlagDefs), 3 }, }; #define NUM_FLAG_LISTS (countof(FlagLists)) @@ -493,7 +488,7 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bo int max = strict ? 2 : NUM_FLAG_LISTS; for (int i = 0; i < max; ++i) { - if (type->IsDescendantOf (*FlagLists[i].Type)) + if ((FlagLists[i].Use & 1) && type->IsDescendantOf (*FlagLists[i].Type)) { def = FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part1); if (def != NULL) @@ -709,9 +704,35 @@ void InitThingdef() sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget)); G_InitLevelLocalsForScript(); - P_InitPlayerForScript(); P_InitStateForScript(); + // set up a variable for the global players array. + PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr); + pstruct->Size = sizeof(player_t); + pstruct->Align = alignof(player_t); + PArray *parray = NewArray(pstruct, MAXPLAYERS); + PField *playerf = new PField("players", pstruct, VARF_Native | VARF_Static, (intptr_t)&players); + GlobalSymbols.AddSymbol(playerf); + + + // this needs to be done manually until it can be given a proper type. + RUNTIME_CLASS(AActor)->AddNativeField("DecalGenerator", NewPointer(TypeVoid), myoffsetof(AActor, DecalGenerator)); + + // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. + for (auto &fl : FlagLists) + { + if (fl.Use & 2) + { + for(int i=0;i 0) // skip the deprecated entries in this list + { + const_cast(*fl.Type)->AddNativeField(FStringf("b%s", fl.Defs[i].name), (fl.Defs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), fl.Defs[i].structoffset, fl.Defs[i].varflags, fl.Defs[i].flagbit); + } + } + } + } + FAutoSegIterator probe(CRegHead, CRegTail); while (*++probe != NULL) diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index f2edca9b9..10ac4bb7b 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -1061,7 +1061,12 @@ struct AFuncDesc #define DEFINE_FIELD_X(cls, icls, name) \ static const FieldDesc VMField_##icls##_##name = { "A" #cls, #name, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), 0 }; \ extern FieldDesc const *const VMField_##icls##_##name##_HookPtr; \ - MSVC_FSEG FieldDesc const *const VMField_##icls##_##name##_HookPtr GCC_FSEG = &VMField_##cls##_##name; + MSVC_FSEG FieldDesc const *const VMField_##icls##_##name##_HookPtr GCC_FSEG = &VMField_##icls##_##name; + +#define DEFINE_FIELD_NAMED_X(cls, icls, name, scriptname) \ + static const FieldDesc VMField_##icls##_##scriptname = { "A" #cls, #scriptname, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), 0 }; \ + extern FieldDesc const *const VMField_##icls##_##scriptname##_HookPtr; \ + MSVC_FSEG FieldDesc const *const VMField_##icls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##icls##_##scriptname; #define DEFINE_FIELD_X_BIT(cls, icls, name, bitval) \ static const FieldDesc VMField_##icls##_##name = { "A" #cls, #name, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), bitval }; \ diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/scripting/zscript/zcc-parse.lemon index 80057724c..fc1803f1d 100644 --- a/src/scripting/zscript/zcc-parse.lemon +++ b/src/scripting/zscript/zcc-parse.lemon @@ -295,8 +295,9 @@ struct_flags(X) ::= NATIVE. { X.Flags = ZCC_Native; } opt_struct_body(X) ::= . { X = NULL; } opt_struct_body(X) ::= struct_body(X). +opt_struct_body(X) ::= error. { X = NULL; } + -struct_body(X) ::= error. { X = NULL; } struct_body(X) ::= struct_member(X). struct_body(X) ::= struct_member(A) struct_body(B). { X = A; /*X-overwrites-A*/ X->AppendSibling(B); } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 72bfcf735..ac9a8825c 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1274,7 +1274,9 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray &Fiel PType *fieldtype = DetermineType(type, field, field->Names->Name, field->Type, true, true); // For structs only allow 'deprecated', for classes exclude function qualifiers. - int notallowed = forstruct? ~ZCC_Deprecated : ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override; + int notallowed = forstruct? + ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Meta | ZCC_Extension : + ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Extension; if (field->Flags & notallowed) { @@ -1323,13 +1325,15 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray &Fiel { Error(field, "The member variable '%s.%s' has not been exported from the executable.", type->TypeName.GetChars(), FName(name->Name).GetChars()); } - else if (thisfieldtype->Size != fd->FieldSize) + else if (thisfieldtype->Size != fd->FieldSize && fd->BitValue == 0) { Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration. (Internal = %d, External = %d)", type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size); } // Q: Should we check alignment, too? A mismatch may be an indicator for bad assumptions. else { + // for bit fields the type must point to the source variable. + if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32; type->AddNativeField(name->Name, thisfieldtype, fd->FieldOffset, varflags, fd->BitValue); } } @@ -1427,6 +1431,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n case ZCC_FloatAuto: retval = formember ? TypeFloat32 : TypeFloat64; + break; case ZCC_Float64: retval = TypeFloat64; diff --git a/src/scripting/zscript/zcc_parser.h b/src/scripting/zscript/zcc_parser.h index e000da06c..a2fc3fb56 100644 --- a/src/scripting/zscript/zcc_parser.h +++ b/src/scripting/zscript/zcc_parser.h @@ -164,6 +164,11 @@ struct ZCC_TreeNode // Appends a sibling to this node's sibling list. void AppendSibling(ZCC_TreeNode *sibling) { + if (this == nullptr) + { + // Some bad syntax can actually get here, so better abort so that the user can see the error which caused this. + I_FatalError("Internal script compiler error. Execution aborted."); + } if (sibling == NULL) { return; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index b3f48acae..0f28de335 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -1,5 +1,7 @@ class Object native { + native bool bDestroyed; + // These really should be global functions... native static int G_SkillPropertyInt(int p); native static double G_SkillPropertyFloat(int p); @@ -35,12 +37,10 @@ class ActorIterator : Object native class DropItem : Object native { - /* native fields listed for reference only for now native readonly DropItem Next; native readonly name Name; native readonly int Probability; - native readonly int Amount; - */ + native int Amount; } class SpotState : Object native diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index b5b60481a..68b81dc2b 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -1,5 +1,6 @@ // for flag changer functions. const FLAG_NO_CHANGE = -1; +const MAXPLAYERS = 8; enum EStateUseFlags { diff --git a/wadsrc/static/zscript/doom/weaponchaingun.txt b/wadsrc/static/zscript/doom/weaponchaingun.txt index 92b3aec46..3766b9b6e 100644 --- a/wadsrc/static/zscript/doom/weaponchaingun.txt +++ b/wadsrc/static/zscript/doom/weaponchaingun.txt @@ -70,7 +70,7 @@ extend class StateProvider { // Removed most of the mess that was here in the C++ code because SetSafeFlash already does some thorough validation. State atk = weap.FindState('Fire'); - State cur = player.GetPSprite(PSP_WEAPON).State; + State cur = player.GetPSprite(PSP_WEAPON).CurState; int theflash = atk == cur? 0:1; player.SetSafeFlash(weap, flash, theflash); } diff --git a/wadsrc/static/zscript/shared/botstuff.txt b/wadsrc/static/zscript/shared/botstuff.txt index cf671ea8b..3ae2d1889 100644 --- a/wadsrc/static/zscript/shared/botstuff.txt +++ b/wadsrc/static/zscript/shared/botstuff.txt @@ -23,3 +23,7 @@ class CajunTrace : Actor +NOTELEPORT } } + +struct Bot native +{ +} diff --git a/wadsrc/static/zscript/shared/inventory.txt b/wadsrc/static/zscript/shared/inventory.txt index 2a9aabe27..929f826da 100644 --- a/wadsrc/static/zscript/shared/inventory.txt +++ b/wadsrc/static/zscript/shared/inventory.txt @@ -102,6 +102,14 @@ class BasicArmor : Armor native class BasicArmorBonus : Armor native { + native double SavePercent; // The default, for when you don't already have armor + native int MaxSaveAmount; + native int MaxAbsorb; + native int MaxFullAbsorb; + native int SaveAmount; + native int BonusCount; + native int BonusMax; + Default { +Inventory.AUTOACTIVATE @@ -438,6 +446,32 @@ class PuzzleItem : Inventory native class Weapon : StateProvider native { + native uint WeaponFlags; + native class AmmoType1, AmmoType2; // Types of ammo used by this weapon + native int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon + native int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon + native int AmmoUse1, AmmoUse2; // How much ammo to use with each shot + native int Kickback; + native float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double) + native sound UpSound, ReadySound; // Sounds when coming up and idle + native class SisterWeaponType; // Another weapon to pick up with this one + native class ProjectileType; // Projectile used by primary attack + native class AltProjectileType; // Projectile used by alternate attack + native int SelectionOrder; // Lower-numbered weapons get picked first + native int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo + native double MoveCombatDist; // Used by bots, but do they *really* need it? + native int ReloadCounter; // For A_CheckForReload + native int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double) + native float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. + native float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. + native Ammo Ammo1, Ammo2; // In-inventory instance variables + native Weapon SisterWeapon; + native float FOVScale; + native int Crosshair; // 0 to use player's crosshair + native bool GivenAsMorphWeapon; + native bool bAltFire; // Set when this weapon's alternate fire is used. + native readonly bool bDehAmmo; + Default { Inventory.PickupSound "misc/w_pkup"; diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 71cdb8479..ed95354f8 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -1,5 +1,31 @@ class PlayerPawn : Actor native { + + native int crouchsprite; + native int MaxHealth; + native int MugShotMaxHealth; + native int RunHealth; + native int PlayerFlags; + native Inventory InvFirst; // first inventory item displayed on inventory bar + native Inventory InvSel; // selected inventory item + + // [GRB] Player class properties + native double JumpZ; + native double GruntSpeed; + native double FallingScreamMinSpeed, FallingScreamMaxSpeed; + native double ViewHeight; + native double ForwardMove1, ForwardMove2; + native double SideMove1, SideMove2; + native TextureID ScoreIcon; + native int SpawnMask; + native Name MorphWeapon; + native double AttackZOffset; // attack height, relative to player center + native double UseRange; // [NS] Distance at which player can +use + native double AirCapacity; // Multiplier for air supply underwater. + native Class FlechetteType; + native color DamageFade; // [CW] Fades for when you are being damaged. + native double ViewBob; // [SP] ViewBob Multiplier + Default { Health 100; @@ -75,10 +101,118 @@ class PlayerChunk : PlayerPawn native class PSprite : Object native { + native readonly State CurState; + native readonly Actor Caller; + native readonly PSprite Next; + native readonly PlayerInfo Owner; + native SpriteID Sprite; + native int Frame; + native readonly int ID; + native Bool processPending; + native double x; + native double y; + native double oldx; + native double oldy; + native Bool firstTic; + native int Tics; + native bool bAddWeapon; + native bool bAddBob; + native bool bPowDouble; + native bool bCVarFast; + native bool bFlip; } -struct PlayerInfo native // this is what internally is player_t +struct PlayerInfo native // this is what internally is known as player_t { + native readonly PlayerPawn mo; + native uint8 playerstate; + native uint original_oldbuttons; + native readonly Class cls; + native float DesiredFOV; + native readonly float FOV; + native double viewz; + native double viewheight; + native double deltaviewheight; + native double bob; + native vector2 vel; + native bool centering; + native uint8 turnticks; + native bool attackdown; + native bool usedown; + native uint oldbuttons; + native int health; + native int inventorytics; + native uint8 CurrentPlayerClass; + native int frags[MAXPLAYERS]; + native int fragcount; + native int lastkilltime; + native uint8 multicount; + native uint8 spreecount; + native uint16 WeaponState; + native Weapon ReadyWeapon; + native Weapon PendingWeapon; + native PSprite psprites; + native int cheats; + native int timefreezer; + native int16 refire; + native int16 inconsistent; + native bool waiting; + native int killcount; + native int itemcount; + native int secretcount; + native int damagecount; + native int bonuscount; + native int hazardcount; + native int hazardinterval; + native Name hazardtype; + native int poisoncount; + native Name poisontype; + native Name poisonpaintype; + native Actor poisoner; + native Actor attacker; + native int extralight; + native int16 fixedcolormap; + native int16 fixedlightlevel; + native int morphtics; + native ClassMorphedPlayerClass; + native int MorphStyle; + native Class MorphExitFlash; + native Class PremorphWeapon; + native int chickenPeck; + native int jumpTics; + native bool onground; + native int respawn_time; + native Actor camera; + native int air_finished; + native Name LastDamageType; + native Actor MUSINFOactor; + native int8 MUSINFOtics; + native bool settings_controller; + native int8 crouching; + native int8 crouchdir; + native Bot bot; + native float BlendR; + native float BlendG; + native float BlendB; + native float BlendA; + native String LogText; + native double MinPitch; + native double MaxPitch; + native double crouchfactor; + native double crouchoffset; + native double crouchviewdelta; + native Actor ConversationNPC; + native Actor ConversationPC; + native double ConversationNPCAngle; + native bool ConversationFaceTalker; +/* these are not doable yet +ticcmd_t cmd; +usercmd_t original_cmd; +userinfo_t userinfo; // [RH] who is this? +FWeaponSlots weapons; +*/ + + native void SetPsprite(int id, State stat, bool pending = false); native void SetSafeFlash(Weapon weap, State flashstate, int index); native PSprite GetPSprite(int id);