[ZScript] Dynamic array being lost between levels?

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

[ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

I need some help troubleshooting a fairly complex bit of ZScipt. I've got a dynamic array on the player that appear to be reset on a new level load, causing an index out-of-bounds error, but I'm not sure why or where it's happening. The line in question works fine until a level change.

Code: Select all

VM execution aborted: array access out of bounds. Max.index = 0, current index = 0

Called from TQ_SemiAuto_Weapon.GetMag at :zscript/tq_generic.txt, line 302
Called from TQ_SemiAuto_Weapon.PickNextMag at :zscript/tq_generic.txt, line 294
Called from weapon state TQ_9mm_Pistol.27 in TQ_9mm_Pistol
Called from PSprite.SetState [Native]
Called from PSprite.Tick at gzdoom.pk3:zscript/shared/player.txt, line 1353
Called from PlayerPawn.TickPSprites at gzdoom.pk3:zscript/shared/player.txt, line 413
Called from PlayerPawn.PlayerThink at gzdoom.pk3:zscript/shared/player.txt, line 1248
Download: https://github.com/caligari87/tranquili ... master.zip
Just start a new game, go to the exit, next level, and then try picking a magazine.
Spoiler: If you need help with the controls
8-)
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

Okay, so I tried something on a hunch. The dynamic array was a class inheriting from Thinker. Once I removed the inheritance, it works properly. Why is this?
Spoiler:
8-)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Dynamic array being lost between levels?

Post by Graf Zahl »

Be careful with players! You have no control over the decision whether an existing player is carried over or a new player is spawned when a level is started. They can lose any user-defined variables if a new PlayerPawn is needed.

You also have to be aware of the fact that at any level start at least one dummy PlayerPawn is spawned.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

Well, shoot. So does that mean stuff like this is liable to break?

Code: Select all

class TQ_Player : Doomplayer
{
	double OldAngle, OldPitch;
	double WeaponAngle, WeaponPitch;
	double OldVel;
	double TQStamina,TQStaminaRate;
	int TicKCounter;

	//...snip...

	override void Tick() {
		if (!player || !player.mo || player.mo != self) {
			Super.Tick();
			return;
		}

		WeaponAngle -= (OldAngle - angle);
		OldAngle=angle;
		WeaponAngle *= 0.925;

		//...snip...
	}
}
In fact, here's the whole player code. Does this look sane?
https://github.com/caligari87/tranquili ... player.txt

8-)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Dynamic array being lost between levels?

Post by Graf Zahl »

There's a good reason why the PlayerPawn and PlayerInfo are separate entities.
You can do with the PlayerPawn whatever you like as long as the information does not need to persist for longer than one level but it's a problem to carry over information to a new level. For that you better use an inventory item to hold the information instead of the PlayerPawn itself because that gets handled diferently - and just as important - is always owned by the proper PlayerPawn.

And you always need to be aware of the fact that a short lived dummy PlayerPawn gets spawned when entering a new level.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

So then it's best (and possible) to basically copy my code (variables and tick function) into an inventory item (moving Tick to DoEffect) and have it work the same? I'm still extremely new at this.

8-)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Dynamic array being lost between levels?

Post by Graf Zahl »

No. Do not move Tick to DoEffect. The code must still be called from the player's Tick() function. The calling semantics, even though similar, are not identical.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

So it's just the variables that need to be moved?

Code: Select all

	double OldAngle, OldPitch;
	double WeaponAngle, WeaponPitch;
	double OldVel;
	double TQStamina,TQStaminaRate;
	int TicKCounter;

	const MagAmount = 3;
	array<TQ_MagThinker> Mags;
And then I'd cast that inventory item from the player's tick to change/use them? That seems exceptionally convoluted considering we could have user_ variables on the player in DECORATE.

8-)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Dynamic array being lost between levels?

Post by Graf Zahl »

user_ variables have the same limitation. Under any normal circumstances the variables should survive. The actual problems normally happen when trying to run some code on the short lived temporary players that get spawned when the transition happens. And if the data is inside an inventory item which is only owned by the real player it cannot create a mess.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

Decided to delete my other post and keep it in this thread.

It seems that classes I cast are getting lost from the object that owns them on level change, in this case my weapon.

Code: Select all

if(!invoker.AlreadyInitialized) {
	if(!invoker.Slide) invoker.Slide = new("TQ_SlideThinker");
	if(!invoker.Trigger) invoker.Trigger = new("TQ_TriggerThinker");
	if(!invoker.Chamber) invoker.Chamber = new("TQ_ChamberThinker");
	if(!invoker.Mag) {
		invoker.Mag = null;
		invoker.MagInserted = False;
	}
	invoker.AlreadyInitialized = true;
}
This causes an address zero violation on new level load, I assume because the thinkers attached to the weapon are getting lost. If I take out the "AlreadyInitialized" check, it works but certain data is lost because the thinkers are re-initialized Why is this? They're on a weapon, not a player.

8-)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Dynamic array being lost between levels?

Post by Graf Zahl »

Thinkers are indeed deleted when a map changes. The only ones that persist are inventory items owned by the player because they get moved to a special static thinker statnum before the map transition.

Is there a reason these things need to be thinkers? Normal objects are owned by whatever points to them but thinkers are always owned by the map, so once the map goes away so does the thinker, unless you make it static by changing its statnum to STAT_STATIC. But this should only be done in very special circumstances where any other type of object won't work.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: [ZScript] Dynamic array being lost between levels?

Post by Caligari87 »

I wasn't aware thinkers were owned by the map. I made them thinkers because it seemed logical to have generic component parts of my weapon that "think" for themselves and perform self-contained book-keeping. I then made a meta-weapon which handles some special interaction cases and can be inherited from to make any weapon that has the same components. Basically I want to factor everything into logical parts instead of having a huge monolithic spaghetti-logic loop.

If there's a better way to achieve that goal I'm all ears.

8-)

Return to “Editing (Archive)”