variable length arrays impossible?

Started by FortressCaulfield, Sat 09/11/2024 04:01:19

Previous topic - Next topic

FortressCaulfield

Trying to create a struct that will track an off-screen NPC's journey so they appear to organically always be in the right spot if the player follows them or walks in on them partway. However, some NPCs will have journeys that require only 2 or 3 waypoints, others 10 or more.

I need to be able to fill these out with a variable length of instructions and AGS really doesn't want me to. I don't need to be able to adjust the array's length once created (although that would be nice for other features) but I do need to be able to have different instances of the same struct have different length arrays.

Attempt 1: arrays
struct Journey {
    Character *walker;
    bool walking;
    int steps;
    int step_x[steps];
    int step_y[steps];
    int step_room[steps];
};

Nope! Array size has to be constant. Every journey would have to be as long as the longest one with the shorter ones just having a bunch of empty entries. That's not great.

Attempt 2: linked lists

struct step {
  int x;
  int y;
  int r;
  step *next;
};

Nope! There doesn't seem to be any combination of managed or non-managed pointers that make it happy here.

AGS has to be able to handle this because rooms store hotspots etc as an array, right, and not every room as the same # of hotspots?
"I can hear you! My ears do more than excrete toxic mucus, you know!"

-Hall of Heroes Docent, Accrual Twist of Fate

Crimson Wizard

#1
The article in the manual about dynamic arrays:
https://adventuregamestudio.github.io/ags-manual/DynamicArrays.html

Dynamic arrays in a regular struct will be declared like this:
Code: ags
struct Journey {
    Character *walker;
    bool walking;
    int steps;
    int step_x[];
    int step_y[];
    int step_room[];
};

and then created like this:
Code: ags
Journey j; // assume we have Journey variable created somewhere
j.steps = 10;
j.step_x = new int[j.steps];
j.step_y = new int[j.steps];
j.step_room = new int[j.steps];

or, in case there's a array of Journeys:
Code: ags
Journey j[100]; // array of 100 journeys
// init the 20th journey
j[20].steps = 10;
j[20].step_x = new int[j[20].steps];
j[20].step_y = new int[j[20].steps];
j[20].step_room = new int[j[20].steps];




As for having managed pointers within managed structs, in order to create linked lists and similar,
that's not possible in AGS 3.*, but is possible in AGS 4, which has an extended script compiler which supports more syntax features and nested managed pointers.
https://www.adventuregamestudio.co.uk/forums/ags-engine-editor-releases/ags-4-0-early-alpha-for-public-test/


Crimson Wizard

#2
I did not have time to test my code earlier.

But then I remembered that the script compiler in AGS 3.* has a bug that prevents it from correctly parsing an access to dynamic array in struct, if that struct is also inside a regular array (that is the second case in my previous post).
For that reason compiler throws an error:
> Cannot declare an array of a type containing dynamic array(s)

That is very unfortunate and annoying. We added this as a temporary measure to prevent other bugs, but they were never fixed in the old compiler.
History of this problem:
https://github.com/adventuregamestudio/ags/issues/338

The new compiler in AGS 4 does not have such problems, it may currently have any combination of nested structs and arrays.

I might try look into this problem in v3 compiler, but it's not written well (bad program code), so if it's going to be difficult to fix, then I doubt it's worth spending time on, while there's already a much better v4 script compiler.

Overall I would recommend trying AGS 4. It's marked as "alpha", as it is still in development, but should be relatively stable.

SMF spam blocked by CleanTalk