• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML [SOLVED] Any way to execute a script when you come upon a certain ds_list item?

ds_list_add(dialogueList, "My name is Bob.")
ds_list_add(dialogueList, "I am a builder.", scr_camera_zoom(960, 540));

Is there any way to do this? I am trying to execute a script with 2 arguments once you get to the 2nd added list item where it says "I am a builder." But, what this does is execute scr_camera_zoom right away because it gets read in already.

I am making a visual novel styled game and I am just trying to change things when you come upon certain ds_list items.

I am trying to find an easy way to do this without making code messy. I spent all day trying to get something like this to work, I was wondering if anyone had any ideas?

I know you could do an if statement and check what ds_list item you are on and do action with a script, but that just doesn't seem like a great way to go.

I am currently using a system where you check for a string inside a ds_list item and then remove it, which will then execute a script but the thing is, it is difficult/messy to pass arguments with this method.
 
P

ParodyKnaveBob

Guest
Howdy, FlameRooster,

Have you considered using a DS Grid instead? Or, if it's all too sporadic on how many arguments to pass into how many scripts, etc., then perhaps each list entry that has something extra could also get a DS Map entry (yep, create a new map,) with a script to execute; that script would then call whatever other functions, scripts, etc. with whatever arguments you need.

I hope these ideas help somehow! $:^ J
 
Howdy, FlameRooster,

Have you considered using a DS Grid instead? Or, if it's all too sporadic on how many arguments to pass into how many scripts, etc., then perhaps each list entry that has something extra could also get a DS Map entry (yep, create a new map,) with a script to execute; that script would then call whatever other functions, scripts, etc. with whatever arguments you need.

I hope these ideas help somehow! $:^ J
Thanks for the ideas!

I am trying to make it as flexible as possible so that I can run any script onto any ds_list entry.

If I used a ds_grid or a ds_map, I would have to upload every single script onto every entry, right?
 

FrostyCat

Redemption Seeker
Why not just put an array in that position?
Code:
ds_list_add(dialogueList, "My name is Bob.", "I am a builder", [scr_camera_zoom, 960, 540]);
Then whenever you see an array in the list instead of a string, run the script using script_execute() with other entries in the array as arguments.
 
P

ParodyKnaveBob

Guest
You're welcome!

One way or another, you'd need to connect a script to a piece of text, yes. Here's one way off the top of my head:

Code:
scr_add_dialogue_to_list("My name is Bob.", scr_NULL);
scr_add_dialogue_to_list("I am a builder.", scr_dialogue_ImABuilder);
Code:
/// scr_add_dialogue_to_list(line, script);

var _str_line = argument0,
    _scr = argument1;

ds_list_add(dialogueList, argument0);
dialogueScriptMap[? argument0] = argument1;
Code:
/// scr_NULL() does nothing
Code:
/// scr_dialogue_ImABuilder
scr_camera_zoom(960, 540);
Code:
// wherever your dialogue reading code is
str_line = dialogueList[| _i];
script_execute(dialogueScriptMap[? str_line];
Another way off the top of my head: A Timeline with Moments instead of a DS List.

That said, ninja'd! (Thanks, GMC, for letting us see when new posts come while typing, ha ha.) The Frosty one has a great suggestion. I'm still not used to GML using the new array constructor like that, especially since I'm stuck with GMS 1.4 for the time being. Also, I thought you wanted a script associated with a line of dialogue, hence my thinking along those lines.
 
Why not just put an array in that position?
Code:
ds_list_add(dialogueList, "My name is Bob.", "I am a builder", [scr_camera_zoom, 960, 540]);
Then whenever you see an array in the list instead of a string, run the script using script_execute() with other entries in the array as arguments.
So, from what I gathered in the documentation, I would check the ds_list item with is_array, and if it is true, set the array item as a variable and put it inside script_execute().

The only thing I don't understand: isn't that a 3 dimensional array? How do I put that into script_execute() ? This is the only part that I am confused about.

Or will simply putting the variable inside the script_execute work?

I am going to experiment and see if I can make it work.

I never thought about putting it in an array. I tried similar other ways such as using:

string_char_at(str, {);

and then if it comes upon { , it will treat everything after that as a script by somehow using script_execute(); but I could never make it work.




You're welcome!

One way or another, you'd need to connect a script to a piece of text, yes. Here's one way off the top of my head:

Code:
scr_add_dialogue_to_list("My name is Bob.", scr_NULL);
scr_add_dialogue_to_list("I am a builder.", scr_dialogue_ImABuilder);
Code:
/// scr_add_dialogue_to_list(line, script);

var _str_line = argument0,
    _scr = argument1;

ds_list_add(dialogueList, argument0);
dialogueScriptMap[? argument0] = argument1;
Code:
/// scr_NULL() does nothing
Code:
/// scr_dialogue_ImABuilder
scr_camera_zoom(960, 540);
Code:
// wherever your dialogue reading code is
str_line = dialogueList[| _i];
script_execute(dialogueScriptMap[? str_line];
Another way off the top of my head: A Timeline with Moments instead of a DS List.

That said, ninja'd! (Thanks, GMC, for letting us see when new posts come while typing, ha ha.) The Frosty one has a great suggestion. I'm still not used to GML using the new array constructor like that, especially since I'm stuck with GMS 1.4 for the time being. Also, I thought you wanted a script associated with a line of dialogue, hence my thinking along those lines.

Thanks for the answer Parody! I will look it over if FrostyCat's method doesn't work out. :)
 
Last edited:
P

ParodyKnaveBob

Guest
I'd go with Frosty's. It's a lot cleaner, simpler, and more versatile. To help with that concept:

Why not just put an array in that position?
Code:
ds_list_add(dialogueList, "My name is Bob.", "I am a builder", [scr_camera_zoom, 960, 540]);
Then whenever you see an array in the list instead of a string, run the script using script_execute() with other entries in the array as arguments.
So, from what I gathered in the documentation, I would check the ds_list item with is_array, and if it is true, set the array item as a variable and put it inside script_execute().

The only thing I don't understand: isn't that a 3 dimensional array? How do I put that into script_execute() ? This is the only part that I am confused about.

Or will simply putting the variable inside the script_execute work?

I am going to experiment and see if I can make it work.
You're totally on the right track. (Hooray for people learning what they can from the manual! heheheh) The thing you're missing: that anonymous array at list position 2 is a simple 1D array with a size of 3. Therefore, when you read dialogueList[| i] and find an array, you'd send it directly to a quick extractor script you'd make. Get the size of the array, use index 0 as your script to execute, and use size-1 to fill in script_execute()'s remaining arguments. Beautiful, really.
 

Tsa05

Member
Frosty's solution is best for flexibility.
Do just also remember in general that using the names of scripts in your data to execute on-the-fly will not work properly on the html5 export module.
 

FrostyCat

Redemption Seeker
Do just also remember in general that using the names of scripts in your data to execute on-the-fly will not work properly on the html5 export module.
This is old news. On the HTML5 export, script_execute() with actual script IDs has always worked, and the issue with string script names converted with asset_get_index() has been addressed as far back as 1.4.1767.
 

FrostyCat

Redemption Seeker
Clearly states that it doesn't work. Either GMS or the docs are not right.
This is where I got the news for string script names working again on HTML5:
The release notes for 1.4.1767 said:
Bugs Fixed Since EA551
  • There are a LOT fixed since 1.4.1763! (See the link above and read all the way down to EA525)
  • 0026944 HTML5: asset_get_index does not work for scripts
If I remember correctly, that line in the documentation also dates from around the timeframe of the ticket referencing the limitation.
 
I'd go with Frosty's. It's a lot cleaner, simpler, and more versatile. To help with that concept:




You're totally on the right track. (Hooray for people learning what they can from the manual! heheheh) The thing you're missing: that anonymous array at list position 2 is a simple 1D array with a size of 3. Therefore, when you read dialogueList[| i] and find an array, you'd send it directly to a quick extractor script you'd make. Get the size of the array, use index 0 as your script to execute, and use size-1 to fill in script_execute()'s remaining arguments. Beautiful, really.

This is what I have so far,



Code:
if (is_array(ds_list_find_value(dialogueList, page))) {
    scr_array_to_script(ds_list_find_value(dialogueList, page));
}


//scr_array_to_script
Code:
array = argument0;


size = array_length_1d(array);

script_execute(asset_get_index(0), size-1);

show_debug_message("Script Executed");
The thing that doesn't work currently is script_execute(). I have tried these:

script_execute(asset_get_index(array), size-1);
script_execute(asset_get_index(0), size-1);
script_execute(0, size-1);
script_execute(gml_script_index, size-1);

I really don't understand how you use script_execute() here. I am trying to get the scr_camera_zoom inside the script_execute(). Isn't index 0 nothing? I have tried using script_execute(asset_get_index(0), size-1); and it says it is a call to a non-existent script.

I really appreciate your explanation. I wouldn't have thought of getting the array length and putting it into script_execute as I thought that wouldn't work. Now the script_execute is the only thing that I am stumped on, lol.
 
Last edited:

FrostyCat

Redemption Seeker
The conspicuous absence of actual array content in script_execute() should have told you that's wrong. This is what you should have done.
Code:
///@func scr_array_to_script(payload)
///@param payload
var a = argument0,
    s = a[0];
switch (array_length_1d(a)-1) {
  case 0: return script_execute(s);
  case 1: return script_execute(s, a[1]);
  case 2: return script_execute(s, a[1], a[2]);
  case 3: return script_execute(s, a[1], a[2], a[3]);
  case 4: return script_execute(s, a[1], a[2], a[3], a[4]);
  case 5: return script_execute(s, a[1], a[2], a[3], a[4], a[5]);
  case 6: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6]);
  case 7: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
  case 8: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
  case 9: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
  case 10: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]);
  case 11: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]);
  case 12: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12]);
  case 13: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]);
  case 14: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]);
  case 15: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
  default: return script_execute(s, a);
}
 
The conspicuous absence of actual array content in script_execute() should have told you that's wrong. This is what you should have done.
Code:
///@func scr_array_to_script(payload)
///@param payload
var a = argument0,
    s = a[0];
switch (array_length_1d(a)-1) {
  case 0: return script_execute(s);
  case 1: return script_execute(s, a[1]);
  case 2: return script_execute(s, a[1], a[2]);
  case 3: return script_execute(s, a[1], a[2], a[3]);
  case 4: return script_execute(s, a[1], a[2], a[3], a[4]);
  case 5: return script_execute(s, a[1], a[2], a[3], a[4], a[5]);
  case 6: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6]);
  case 7: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
  case 8: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
  case 9: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
  case 10: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]);
  case 11: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]);
  case 12: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12]);
  case 13: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]);
  case 14: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]);
  case 15: return script_execute(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
  default: return script_execute(s, a);
}
It took me a while to understand this, but holy crap. I didn't know you could access the arguments of an array like that. (I didn't know you could set a variable to an array, and then place [] behind that new variable to access arguments) I am still pretty incompetent. I learn something new everyday. Seriously, thank you! I REALLY appreciate the time you spent helping me out and teaching me.

It is because I didn't have "s" as the first argument, but rather I tried just "a" as I really didn't know you could access the array like that.
 
Top