From c9a994a885c8ccbad15b3464bb974f1600f34341 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sat, 4 Mar 2017 00:04:19 +0200 Subject: [PATCH] Fixed: clearscope should also clear the inherited scope (through struct member access chain); Fixed: struct member access chain should ONLY work for structs (forgot that FxClassMember inherits FxStructMember) --- src/dobjtype.h | 1 + src/scripting/backend/codegen.cpp | 13 ++++++---- src/scripting/backend/codegen.h | 13 +++++++--- src/scripting/zscript/zcc_compile.cpp | 9 ++----- wadsrc/static/zscript/actor.txt | 8 +++---- wadsrc/static/zscript/menu/menu.txt | 2 +- wadsrc/static/zscript/shared/player.txt | 32 ++++++++++++------------- 7 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/dobjtype.h b/src/dobjtype.h index de3b9c916..1d134bd07 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -40,6 +40,7 @@ enum VARF_UI = (1<<20), // [ZZ] ui: object is ui-scope only (can't modify playsim) VARF_Play = (1<<21), // [ZZ] play: object is playsim-scope only (can't access ui) VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only) + VARF_ClearScope = (1<<23), // [ZZ] clearscope: this method ignores the member access chain that leads to it and is always plain data. }; // An action function ------------------------------------------------------- diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 1359df59a..ad3ed7664 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -6879,7 +6879,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx) } BarrierSide = scopeBarrier.sidelast; - if (classx->ExprType == EFX_StructMember) // note: only do this for structs now + if (classx->ExprType == EFX_StructMember && ExprType == EFX_StructMember) // note: only do this for structs now { FxStructMember* pmember = (FxStructMember*)classx; if (BarrierSide == FScopeBarrier::Side_PlainData && pmember) @@ -8175,11 +8175,14 @@ isresolved: innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags); innerflags = FScopeBarrier::FlagsFromSide(innerside); } - if (Self->ExprType == EFX_StructMember) + else if (innerside != FScopeBarrier::Side_Clear) { - FxStructMember* pmember = (FxStructMember*)Self; - if (innerside == FScopeBarrier::Side_PlainData) - innerflags = FScopeBarrier::ChangeSideInFlags(innerflags, pmember->BarrierSide); + if (Self->ExprType == EFX_StructMember) + { + FxStructMember* pmember = (FxStructMember*)Self; + if (innerside == FScopeBarrier::Side_PlainData) + innerflags = FScopeBarrier::ChangeSideInFlags(innerflags, pmember->BarrierSide); + } } FScopeBarrier scopeBarrier(outerflags, innerflags, MethodName.GetChars()); if (!scopeBarrier.callable) diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index c9e23c980..07425bd90 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -89,7 +89,8 @@ struct FScopeBarrier Side_PlainData = 0, Side_UI = 1, Side_Play = 2, - Side_Virtual = 3 // do NOT change the value + Side_Virtual = 3, // do NOT change the value + Side_Clear = 4 }; int sidefrom; int sidelast; @@ -103,6 +104,8 @@ struct FScopeBarrier return Side_Play; if (flags & VARF_VirtualScope) return Side_Virtual; + if (flags & VARF_ClearScope) + return Side_Clear; return Side_PlainData; } @@ -127,6 +130,8 @@ struct FScopeBarrier return VARF_UI; case Side_Virtual: return VARF_VirtualScope; + case Side_Clear: + return VARF_ClearScope; default: return 0; } @@ -144,7 +149,9 @@ struct FScopeBarrier case Side_Play: return "play"; case Side_Virtual: - return "virtual"; // should not happen! + return "virtualscope"; // should not happen! + case Side_Clear: + return "clearscope"; // should not happen! default: return "unknown"; } @@ -153,7 +160,7 @@ struct FScopeBarrier // this modifies VARF_ flags and sets the side properly. static int ChangeSideInFlags(int flags, int side) { - flags &= ~(VARF_UI | VARF_Play | VARF_VirtualScope); + flags &= ~(VARF_UI | VARF_Play | VARF_VirtualScope | VARF_ClearScope); flags |= FlagsFromSide(side); return flags; } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index e28f5d271..1f7e66442 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2135,7 +2135,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool if (f->Flags & ZCC_Play) varflags = FScopeBarrier::ChangeSideInFlags(varflags, FScopeBarrier::Side_Play); if (f->Flags & ZCC_ClearScope) - varflags = FScopeBarrier::ChangeSideInFlags(varflags, FScopeBarrier::Side_PlainData); + varflags = FScopeBarrier::ChangeSideInFlags(varflags, FScopeBarrier::Side_Clear); if (f->Flags & ZCC_VirtualScope) varflags = FScopeBarrier::ChangeSideInFlags(varflags, FScopeBarrier::Side_Virtual); @@ -2405,12 +2405,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool if (sym->Variants[0].Implementation != nullptr) { // [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed. - if (varflags & VARF_UI) - sym->Variants[0].Implementation->BarrierSide = FScopeBarrier::Side_UI; - if (varflags & VARF_Play) - sym->Variants[0].Implementation->BarrierSide = FScopeBarrier::Side_Play; - if (varflags & VARF_VirtualScope) - sym->Variants[0].Implementation->BarrierSide = FScopeBarrier::Side_Virtual; + sym->Variants[0].Implementation->BarrierSide = FScopeBarrier::SideFromFlags(varflags); } PClass *clstype = static_cast(c->Type()); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 148fd4bd5..56d9072fa 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -425,7 +425,7 @@ class Actor : Thinker native } } - virtual String GetObituary(Actor victim, Actor inflictor, Name mod, bool playerattack) + clearscope virtual String GetObituary(Actor victim, Actor inflictor, Name mod, bool playerattack) { if (mod == 'Telefrag') { @@ -450,13 +450,13 @@ class Actor : Thinker native native static int FindUniqueTid(int start = 0, int limit = 0); native void SetShade(color col); - native string GetTag(string defstr = ""); + clearscope native string GetTag(string defstr = ""); native void SetTag(string defstr = ""); native double GetBobOffset(double frac = 0); native void ClearCounters(); native bool GiveBody (int num, int max=0); native bool HitFloor(); - native bool isTeammate(Actor other); + clearscope native bool isTeammate(Actor other); native int PlayerNumber(); native void SetFriendPlayer(PlayerInfo player); native void SoundAlert(Actor target, bool splash = false, double maxdist = 0); @@ -597,7 +597,7 @@ class Actor : Thinker native native void ClearInventory(); native bool GiveInventory(class type, int amount, bool givecheat = false); native bool TakeInventory(class itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false); - native Inventory FindInventory(class itemtype, bool subclass = false); + clearscope native Inventory FindInventory(class itemtype, bool subclass = false); native Inventory GiveInventoryType(class itemtype); native Inventory DropInventory (Inventory item, int amt = -1); native bool UseInventory(Inventory item); diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index b4e5c1ac8..81727ad2b 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -287,7 +287,7 @@ class Menu : Object native ui } -class MenuDescriptor : Object native +class MenuDescriptor : Object native ui { native Name mMenuName; native String mNetgameMessage; diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index a80210714..d6ea5b843 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -150,7 +150,7 @@ class PlayerPawn : Actor native } // This is for SBARINFO. - int, int GetEffectTicsForItem(class item) + clearscope int, int GetEffectTicsForItem(class item) { let pg = (class)(item); if (pg != null) @@ -167,10 +167,10 @@ class PlayerPawn : Actor native return -1, -1; } - native int GetMaxHealth(bool withupgrades = false); + clearscope native int GetMaxHealth(bool withupgrades = false); native bool ResetAirSupply (bool playgasp = false); native void CheckWeaponSwitch(class item); - native static String GetPrintableDisplayName(Class cls); + clearscope native static String GetPrintableDisplayName(Class cls); } @@ -192,7 +192,7 @@ class PlayerChunk : PlayerPawn } } -class PSprite : Object native +class PSprite : Object native play { enum PSPLayers { @@ -237,7 +237,7 @@ enum EPlayerState PST_GONE // Player has left the game } -struct PlayerInfo native // this is what internally is known as player_t +struct PlayerInfo native play // this is what internally is known as player_t { // technically engine constants but the only part of the playsim using them is the player. const NOFIXEDCOLORMAP = -1; @@ -338,22 +338,22 @@ usercmd_t original_cmd; native void PoisonDamage(Actor source, int damage, bool playPainSound); native void SetPsprite(int id, State stat, bool pending = false); native void SetSafeFlash(Weapon weap, State flashstate, int index); - native PSprite GetPSprite(int id); - native PSprite FindPSprite(int id); + native PSprite GetPSprite(int id) const; + native PSprite FindPSprite(int id) const; native void SetLogNumber (int text); native void SetLogText (String text); native void DropWeapon(); native void BringUpWeapon(); - native String GetUserName(); - native Color GetColor(); - native int GetColorSet(); - native int GetPlayerClassNum(); - native int GetSkin(); - native bool GetNeverSwitch(); - native int GetGender(); - native int GetTeam(); - native float GetAutoaim(); + native String GetUserName() const; + native Color GetColor() const; + native int GetColorSet() const; + native int GetPlayerClassNum() const; + native int GetSkin() const; + native bool GetNeverSwitch() const; + native int GetGender() const; + native int GetTeam() const; + native float GetAutoaim() const; native void SetFOV(float fov); }