Problem with Arrays in zscript

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
ZoDX32
Posts: 20
Joined: Sat Oct 14, 2017 5:49 pm

Problem with Arrays in zscript

Post by ZoDX32 »

So i wanted actor have some classes for being like variables storage, and this is what i get:

What am i doing wrong here? (This is only main part of script)

Code: Select all

version "4.2"

const box_triangles = 12; //if no MD3 has been found, make standard box shape.

struct vector3d {
	vector3 p1;
	vector3 p2;
}

class Tris {
	vector3 normal;
	float rad; //Radius, for check
	vector3 p1;
	vector3 p2;
	vector3 p3;
}

class PhysModel {
	Array<class<Tris> > tri;
	float friction;
	int Type;
}

class PhysActor : Actor { //Kinda :P
	class<PhysModel> Body; //This is gonna be the actor's NEW BODY! (Instead of his box shaped body)
	
	override void PostBeginPlay() {
		Actor mo, mo2; //temp actors
		
		if(Body == null) {
			//Body = new('PhysModel');
			Tris tri_temp = new('Tris');
			
			vector3 p_temp[box_triangles * 3] = {
				(radius, radius/2, -height/2),
				(radius, -radius/2, -height/2),
				(radius, radius/2, height/2)
			};
			
			for(int i = 0; i < 1; i++) { //1 for testing, set it to "box_triangles" maybe..
				tri_temp.p1 = p_temp[3 * i + 0];
				tri_temp.p2 = p_temp[3 * i + 1];
				tri_temp.p3 = p_temp[3 * i + 2];
				
				Body.Tri.Push(tri_temp);
			}
			Body.type = 0;
		}
		
		for(int i2 = 0; i2 < Body.Tri.Size(); i2++) {
			Body.Tri[i2].normal = CalculateNormal(Body.Tri[i2].p1, Body.Tri[i2].p2, Body.Tri[i2].p3);
			
			for(int i3 = 0; i3 < 3; i3++) { //Find farthest point in triangle
				vector3 temp_point;
				
				switch(i3) {
					case 0:
						temp_point = Body.Tri[i2].p1;
					case 1:
						temp_point = Body.Tri[i2].p2;
					case 2:
						temp_point = Body.Tri[i2].p3;
				}
				
				mo = Spawn("MapSpot", pos + temp_point);
				mo2 = Spawn("MapSpot", pos + Body.Tri[i2].normal);
				
				Body.Tri[i2].rad = mo.Distance3D(mo2);
				
				mo.Destroy();
				mo2.Destroy();
			}
		}
		Super.PostBeginPlay();
	}

	Array<class<Actor> > CheckActor; //clear after each implements, cuz this is a variable, not actor. This is CheckActor, they've been checked while nearby triangle.
	
	override void Tick() {
		for(int i = 0; i < Body.Tri.Size(); i++) {
			Actor mo, mo2; //temp actors
			float check_dist; //Tri's check size (or just distance from normal to points)
			
			//Distance from tri's normal to actor
			mo = Spawn("MapSpot", pos + vel); //velocity of actor
			mo2 = Spawn("MapSpot", pos + Body.Tri[i].normal); //normal's position
			check_dist = Body.Tri[i].rad + Distance3D(mo) + 8;
			mo.Destroy();
			
			//Find nearest actors to check
			ThinkerIterator AF = ThinkerIterator.Create("Actor");
			
			while(mo = Actor(AF.Next())) if(mo2.Distance3D(mo) <= check_dist && mo is "PhysActor" && mo != self) {
				CheckActor.Push(mo);
			}
			mo2.Destroy();
			
			//Finally we are done with implementing CheckActor!
			//Now let's move our PhysActor!
			if(CheckActor[0] != null) {
				for(int i2 = 0; i2 < CheckActor.Size(); i2++) {
					let pmo = PhysActor(CheckActor[i2]); //PMO - Physical Main Object :P
					
					console.printf("checking actor %s", pmo.GetClassName());
				}
			}
			
			//Clear checkactors
			CheckActor.Clear();
			mo.Destroy();
			mo2.Destroy();
		}
		
		Super.Tick();
	}
}
Script error lines:

Code: Select all

126: Body.Tri.Push(tri_temp);
128: Body.type = 0;
131: for(int i2 = 0; i2 < Body.Tri.Size(); i2++) {
163: for(int i = 0; i < Body.Tri.Size(); i++) {
Also, Push() doesn't even work, not putting item to array index, and the array maximum index stays 0, which cause "read from address zero, write to address zero". (But Push() does work with integers...)
Only because of arrays and classes i stuck with getting that error...
Spoiler:
Last edited by ZoDX32 on Thu Nov 14, 2019 11:46 am, edited 8 times in total.
User avatar
Cherno
Posts: 1311
Joined: Tue Dec 06, 2016 11:25 am

Re: Problem with Arrays in zscript

Post by Cherno »

1. If any code is not relevant to the question, it would be nice if you would just leave it out.
2. To delcare an array, you just use the syntax Array<Actor> (or Array<int> or whatever).
User avatar
ZoDX32
Posts: 20
Joined: Sat Oct 14, 2017 5:49 pm

Re: Problem with Arrays in zscript

Post by ZoDX32 »

Cherno wrote:1. If any code is not relevant to the question, it would be nice if you would just leave it out.
2. To delcare an array, you just use the syntax Array<Actor> (or Array<int> or whatever).
i updated the post.
Array don't want to work with "class" or "actor", but does work with "int".
What i need it's "class" to be in array by Push(), and same for "actor". Because what i get it's that error and "write to address zero".
User avatar
phantombeta
Posts: 2088
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Problem with Arrays in zscript

Post by phantombeta »

"Class<[class name]>" refers to a class type, not a class instance. For a variable that points to a class instance, you just use the class name as the type.
You also never assign anything to it, so it'll always be null.
User avatar
ZoDX32
Posts: 20
Joined: Sat Oct 14, 2017 5:49 pm

Re: Problem with Arrays in zscript

Post by ZoDX32 »

So if i want to create class from type(name) inside of my PhysActor, i need to do like this?

Code: Select all

PhysModel Body;
and inside of PhysModel the array class:

Code: Select all

Array<Tris> tri;
But then if i don't have to try "make them exist":

Code: Select all

Body = new('PhysModel');
I get this.
But if i use that i get this.

It seems Array (Push()) still don't want to work with my new classes, and with actors too, but it works with integers.
User avatar
Tartlman
Posts: 226
Joined: Thu Oct 11, 2018 5:24 am
Location: meme hell
Contact:

Re: Problem with Arrays in zscript

Post by Tartlman »

Array<> should work fine with actors. Just do array<actor>, and you can shove any actor you like in there.

Keep in mind that if the obvious solution doesn't work, a gross and hacky one might, as arrays are finicky. To quote from marrub:
arrays are cursed
abandon all hope ye who enter
User avatar
ZoDX32
Posts: 20
Joined: Sat Oct 14, 2017 5:49 pm

Re: Problem with Arrays in zscript

Post by ZoDX32 »

Hold on... I think i'm figuring out...
User avatar
phantombeta
Posts: 2088
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Problem with Arrays in zscript

Post by phantombeta »

Tartlman wrote:Array<> should work fine with actors. Just do array<actor>, and you can shove any actor you like in there.

Keep in mind that if the obvious solution doesn't work, a gross and hacky one might, as arrays are finicky. To quote from marrub:
arrays are cursed
abandon all hope ye who enter
I literally just told you that most (if not all) array bugs got fixed in versions newer than the ancient version you're using. -_-
User avatar
ZoDX32
Posts: 20
Joined: Sat Oct 14, 2017 5:49 pm

Re: Problem with Arrays in zscript

Post by ZoDX32 »

I solved problem, i did this:
zscript/main/structs.txt

Code: Select all

class Tris3D : Object {
	vector3 normal;
	vector3 p[3];
	vector3 mp[3];	//momentum point
	//float nangle	//normal angle
	//float npitch	//normal pitch
	//float nroll	//normal roll
}
zscript/main/physactor.txt

Code: Select all

class PhysActor : actor {
	Array<Tris3D> tri;
	
	<some function begins>
		for(int i = 0; i < box_tri; i++) {
			tri.Push(new('Tris3D'));

			tri[i].p[0] = <some point>;
			tri[i].p[1] = <some point>;
			tri[i].p[2] = <some point>;
			tri[i].normal = CalculateNormal(tri[i].p[0], tri[i].p[1], tri[i].p[2]);
		}
	<some function ends>
}
I used Object instead class or struct. Now everything works.
Thanks for help!
Post Reply

Return to “Scripting”