Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Jenoclip

[ZSCript] Referring to a class member causes VM to crash

Recommended Posts

𝘽𝙧𝙞𝙚𝙛 𝙞𝙣𝙛𝙤:

  • Language: ZScript V 4.8.2
  • Port: GZDoom V 4.8.2
  • Error occurrence stage: Class executes code

I have a class inherited from Actor, inside it (in the body of the class, not in Default and not in States) is declared a class storing global variables, from this class I need to read dynamic arrays of TL_Group and IS_Group classes that store information, and I can't get this information, because for some reason VM gives an error about calling to null address when I try to read a member of the class.
And with all this 1 class in the dynamic array is definitely stored and I can refer to this class to, for example, set the test class of IS_Group type to the same value, but no matter what crutches I tried to do it, I still have VM crashes saying that it can not read the null address.

Global Vars:

Class GEN_GlobalVars : Thinker
{
    Array<TL_Group> TagLinker_Groups;
    Array<IS_Group> ItemSpawner_Groups;

    //...
    //Declaring other variables
    //...

    #region /*Constants & Enums*/
    //Some code not related to the problem
    #endregion
    
    Static Play GEN_GlobalVars Get(Void)
    {
        GEN_GlobalVars GlbCls = GEN_GlobalVars(ThinkerIterator.Create("GEN_GlobalVars", STAT_Static).Next());

        If(!GlbCls)
        {
            GlbCls = New("GEN_GlobalVars");
            GlbCls.ChangeStatNum(STAT_Static);
        }
        
        Return GlbCls;
    }
}



What TL_Group is:

Class TL_Group
{
    UInt iMinTag;
    UInt iMaxTag;
    String iStageName;

    Static TL_Group Create(UInt MinTag, UInt MaxTag, String StageName)
    {
        TL_Group Init_Value = TL_Group(new("TL_Group"));

        Init_Value.iMinTag = MinTag;
        Init_Value.iMaxTag = MaxTag;
        Init_Value.iStageName = StageName;

        Return Init_Value;
    }
}


Class&Vars declaration:

Class GEN_LevelGen : Actor
{
    Default
    {
        +NoInteraction;
        +DontThrust;
        +DontInterpolate;
        RenderStyle "None";
    }
    Int TempVal1;
    Int TempVal2;
    Array<Int> TempIArr1;
    Int TempVal3;
    Int TempVal4;
    Int TempVal5;
    Int Stage;
    String StageName;
    Double TempDVal6;
    Array<String> TempSArr1;

    GEN_GlobalVars GVars;
    
    Void ZS_SpawnSpotForced(Int SpotTID, String WhatToSpawn, Int Replace)
    {
        ActorIterator Spotsiterator = Level.CreateActorIterator(SpotTID);
        Actor Spot;
        Actor Spawned;

        While(Spot = Spotsiterator.Next())
        {
            Spawned = Spawn(WhatToSpawn, Spot.Pos, Replace);
            Spawned.Angle    =    Spot.Angle;
            Spawned.Roll    =    Spot.Roll;
            Spawned.Pitch    =    Spot.Pitch;
        }
    }
    
    Bool IsTIDUsed(Int TID)
    {
        Return (Level.CreateActorIterator(TID).Next() != Null);
    }
    
    Double RoundTo(Double Num, UInt DecimalPlaces = 0)
    {
        Return Round(Num * (DecimalPlaces + 1))/(DecimalPlaces + 1);
    }
    
    Double NoZero(Double Val)
    {
        If(Val == 0.0)    {Return 1.0;}
        Else            {Return Val;}
    }
    
    Double GetPercent(Void)
    {
        Switch(Stage)
        {
            Case 1:
                Return
                (GVars.TagLinker_Groups.Size() + TempVal1)/
                NoZero(GVars.TagLinker_Groups.Size() + GVars.ItemSpawner_Groups.Size());
            Default:
                Return
                TempVal1/
                NoZero(GVars.TagLinker_Groups.Size() + GVars.ItemSpawner_Groups.Size());
        }
    }

    States
    {
        Spawn:
            TNT1 A 1;
            TNT1 A 0
            {
                GVars = GEN_GlobalVars.Get();
                GVars.RenderRequest = RenderInfoPacket.Create(
                GVars.RIP_BGColor, -1, -1, "|MN", 0.0,
                0.0, "|MN", False, 0x000000, 1.0
                );
                TempVal1 = 0;
                TempVal2 = 0;
                TempVal3 = 0;
                TempVal4 = 0;
                TempVal5 = 0;
            }
    //...

 

Erroneous string:

        TagLinker_Loop:
            TNT1 A 1
            {
                Stage = 0;
                If(TempVal2 == -1)
                {
                    TempVal2 = 0;
                    TempVal5 = 0;
                    TempVal1 += 1;
                }
                If(TempVal1 > (GVars.TagLinker_Groups.Size()-1))
                {
                    TempVal1 = 0;
                    TempVal2 = 0;
                    TempVal3 = 0;
                    TempVal4 = 0;
                    TempVal5 = 0;
                    Return ResolveState("ItemSpawner_Loop");
                }
/*—————————————————————————>>>>*/StageName = GVars.TagLinker_Groups[TempVal1].iStageName;//<<<< VM execution aborted: tried to read from address zero, line 406
                GVars.RenderRequest = RenderInfoPacket.Create(
                GVars.RIP_GenInfo, True, RoundTo((GetPercent()*100.0), 2),
                StageName);
                TempVal3 = GVars.TagLinker_Groups[TempVal1].iMinTag;
                TempVal4 = GVars.TagLinker_Groups[TempVal1].iMaxTag;
                TempIArr1.Clear();
                TempVal5 = Random(TempVal3, TempVal4);
                TempVal2 = TempVal3;
                Return ResolveState(null);
            }

How do I solve this?
(Sorry for the not so good English)

Share this post


Link to post

For complex ZScript questions like these it's better to ask in a place like the ZDoom Discord server instead. Since the questions section on Doomworld is mainly for mapping and simple DECORATE questions.

 

As for the question itself, you've probably tried this. But have you tried to null check if the actual TL_Group class in that index is not null ? Something like

If (GVars.TagLinker_Groups[TempVal1]) //Check if the index at TempVal1 is not null.
{
	//If it isn't, run the other code here, like setting the value of StageName based on the iStageName of that particular class in the array.
}

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×