The Dink Network

Script interference

July 22nd 2018, 07:44 AM
duck.gif
toof
Peasant He/Him
I disagree. 
I've decided to open new thread on this one. I'm having a really dumb issue...
--The Plot--

I've made a bar scene with two scripts so far. One with bartender and necessary for the story progression, and the other attached to one of the sprites that is supposed to make random chat between two sprites.

--The Plot Thickens--
Each script functions well (except that one bug ), but when I start talking to bartender, if the timing is right (and often it is), bartender script just stops executing in the middle, and Dink is left frozen.

When I say it functions well, I mean that bartender script works just fine when I remove the bar chat

This occurs especially when I use space to fast forward talking. When Dink is talking, it skips it normally, but when it comes to bartender, it sometimes skips his line, or starts skipping the lines of the two 'chatting' sprites, at which point bartender's script stops executing... most of the time.

--The Spoilers--
I'll include some basic information that might help:

bar chat script
void main (void)
{
	int &pl = sp(48);
	int &pr = sp(49);
	int &tbl = sp(37);
	int &rand;
	loop:
	&rand = random(6,1);
	if(&rand == 1)
	{
		wait(2000);
		say_stop("`1Have you ever hear of any other rhythm?",&pl);
        //and so forth

This script is attached to sprite number 49 ( he is in the script also, second variable )

bartender script
void talk(void)
{
	//bartender
	int &pleft;
	&pleft = sp(50);
	int &pright;
	&pright = sp(51);
	int &btd;
	&btd = sp(41);
	sp_base_walk(&btd, 380);
	freeze(&btd);
	wait(1);
	freeze(1);
	say_stop("`@Yo, bartender!", 1);
	say_stop("`9Yo!", &btd);
	say_stop("`@What you got here?", 1);
	say_stop("`9What'ya need?", &btd);
	cho_loop:
	choice_start();
        //and so on...

This piece of garbage is attached to desk (sprite number 13, not present in the script)

Any ideas?
July 22nd 2018, 09:01 AM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Well, if I understand it right, you already know what your issue is. While Dink is frozen, the original script is interfering, making the bartender say a line of text, and then the rest of his script is not executing, resulting in dink remaining frozen. Is this correct?

If so, there are multiple ways you could approach the fix.
But first, I just want to mention, it is not advisable to store sprites in variables using there editor numbers with sp(#), as sprite numbers can change. I think this is also warned in the DinkC reference, in saying that, I've used them before in certain situation and it works fine. If you want to be safe, store the sprite in a global. Or don't, it's up to you.

Now, one simple way without changing everything around would be to simply disable the other script from interfering at any point that dink should be talking to the bartender. You could simply set the bartender's gold value to 1 (this is like an extra little local variable you can use, sort of).

So right before freezing dink:

sp_gold(&current_sprite, 1);

and after dink is unfreezed:

sp_gold(&current_sprite, 0);

Then in the other script you can do a check, and if the bartenders gold value is 1, do not proceed with the conversation, simply go back to the loop.
Eg:

int &check = sp_gold(&pr, -1);
if (&check != 0) goto loop;

make sure there's a wait in between the loop, and the goto command as well, to prevent extreme lag.
I'm sure others will offer other fixes, but this a simple one, that will work.
July 22nd 2018, 09:37 AM
duck.gif
toof
Peasant He/Him
I disagree. 
Omg!
This is gonna be a really pain in the @$$, since I plan to have multiple conversations on the same screen. Adding that to every possible script. Oh well...
This is the freakiest language I've ever used yet.

EDIT
But thanks for the answer. I'll try to implement that later, when I make sure the rest of the scripts are working on their own.
July 22nd 2018, 01:10 PM
wizardg.gif
LeprochaUn
Peasant He/Him Japan bloop
Responsible for making things not look like ass 
If you want multiple conversations running on the same screen that are sort of background conversations just use say() instead of say_stop().
July 22nd 2018, 01:54 PM
custom_king.png
redink1
King He/Him United States bloop
A mother ducking wizard 
Or say_stop_npc
July 22nd 2018, 04:09 PM
wizardg.gif
LeprochaUn
Peasant He/Him Japan bloop
Responsible for making things not look like ass 
right yes, that too.
July 22nd 2018, 06:18 PM
duck.gif
toof
Peasant He/Him
I disagree. 
say_stop_npc() (non-interfering text display)

@Redink1
I guess that will do
thank you very much

Changing every say_stop() to say() and adding wait() behind every line is not an option, this crap has almost 300 lines
July 24th 2018, 08:49 PM
duck.gif
toof
Peasant He/Him
I disagree. 
It's cooking... slowly though...
Greetings from Newbielandistan, I present, and ask, yet another question. I have this script on one sprite (still bartender), and at some point, I need to move Dink to another screen (let's say 2), and have an interactive cutscene / quest. After that, Dink must be returned back to original screen (let's say 1), have a mini cutscene dialogue that informs him of his success/failure, and then unfreeze(1);
What would be the proper way to make that transition? I have an entire script done, but can't test it, 'cause transition.

excerpt of the bartender script, screen 1
void talk(void)
{
 //some crap
 fade_down();
 &help_var = 2; //global var, should activate script on screen 2
 &player_map = 2;
}
void main(void)
{
  //this is supposed activate that short cutscene
  //when Dink returns to this screen
  if(&help_var ==3)
  {
     fade_up();
     sp_nodraw(1,0);
     sp_x(1,220);
     sp_y(1,180); //nevermind if coordinates are right
     freeze(1);
     //the dialog goes here, it's all done
     &help_var = 10 //this ensures that some task is done
  }
}

excerpt of the script attached to a table, screen 2
void main(void)
{
  if(&help_var ==2)
  {
  fade_up();
  sp_nodraw(1,0);
  sp_x(1,220);
  sp_y(1,180);
  //cutscene and all that
  &job_done = 1; //needed for the first screen, also global
  fade_down();
  &player_map = 1;
  }
}

I've tried adding load_screen(), draw_screen(), script_attach()... But... Again, it's probably some dumb detail...
July 25th 2018, 09:27 AM
spike.gif
SlipDink
Peasant He/Him United States bloop rumble
2nd generation. No easy way to be free. 
DinkC is generally pretty picky about the use of ONE space around each side of any of it's operators. I don't know whether or not this is the root of your problems, but I can tell you that this:

if(&help_var ==3)
should be
if (&help_var == 3)
and this
if(&help_var ==2)
should be
if (&help_var == 2)
.

You don't actually need the space after if, but you DO need exactly one space on each side of the == sign. Don't believe me? COPY EXACTLY this short piece of code as key-68.c and get Dink to a blank "New Screen". Then press the letter D (for Dink of course!) on your keyboard.

void main( void )
{
	script_attach(1000);
	freeze(1);
	if(1 == 0)
		say_stop("if(1 == 0) with spaces around numbers FAILS",1);
	else
		say_stop("if(1 == 0) with spaces around numbers works correctly",1);
	if (1 == 0)
		say_stop("if (1 == 0) with spaces around numbers and after if FAILS",1);
	else
		say_stop("if (1 == 0) with spaces around numbers and after if works correctly",1);
	if(1==0)
		say_stop("if(1==0) with no spaces around numbers FAILS",1);
	unfreeze(1);
	kill_this_task();
}


July 25th 2018, 10:28 AM
duck.gif
toof
Peasant He/Him
I disagree. 
@SlipDink
Yeah, I'm aware of that. I've mistyped the code, because copying it in here doesn't work as desired, and I type as you've shown anyways, because the code is more readable. I'm also aware that this can cause problems:
&var = &var + 1;

and should be switched with:
&var += 1;


My question is how to make script attached to a certain sprite, start an interactive cutscene (or cutscene in general) on the other screen, because the sprite that script is attached to, is not on the same screen. Thus, I've just used &player_map to relocate it to another, and attached void main(void) procedure to another sprite on the target screen, that contains certain conditions which will activate it. However, it doesn't work. Maybe I should use spawn() or something?
I'm experimenting while I'm writing here, actively trying to solve the problem, but screen transitions can be really messy in here.

Edit:
I think I've got it
July 26th 2018, 07:05 PM
wizardg.gif
LeprochaUn
Peasant He/Him Japan bloop
Responsible for making things not look like ass 
because the sprite that script is attached to, is not on the same screen.

script_attach(1000) moves the script onto sprite 1000, and shouldn't have any issues continuing on another screen.
If you change screens the sprites that script knows will be gone, yes. In this case you'd probably want to create_sprite() what you need within the script.
July 26th 2018, 07:39 PM
duck.gif
toof
Peasant He/Him
I disagree. 
@LeprochaUn
and shouldn't have any issues continuing on another screen.
Yeah, but I also wanted to return to previous screen after that thing was finished, and continue the original script from the specific line. Now this is outright impossible (probably), and I've found that the most simple solution was to put spawn("desired_script") into the bartender script ( man, this is getting confusing ), and to do the rest from there on.
Everything is working fine now, I've even done most of the debugging, I'm still unaware of what DinkC is capable/incapable of.

The reason I'm asking all of this, isn't because I'm lazy to test it myself, but because it's taking too much time to do it, and there is no tutorial on such things, only the basics (shame on the community, SHAME!! ). It really derails me from making any progress... and hardness editing

But for now, I'm making some progress, and hopefully, I'll ask for a beta tester soon. If I don't make this thing now, I'm probably never going to finish a single dmod...
July 31st 2018, 09:34 AM
duck.gif
toof
Peasant He/Him
I disagree. 
One more thing...

I'm scripting one sprite on the screen. He has void main(void) function, and he is talking with other characters on some random topics. But when I talk to him, the entire script attached to him stops working. The conversation doesn't even start. Is this a limitation to the engine, or is there a workaround?

Here's roughly how it looks like:
void main(void)
{
  int &rand;
  loop:
  &rand = random(2,1);
  if(&rand == 1)
  {
    //conversation with other npcs, using say_stop_npc();
  }
  //etc
  goto loop;
}

void talk(void)
{
  //say_stop() and the rest
}


I'm aware that void main(void) stuff won't continue after talking, until I reenter the screen, but I just need void talk(void) to start...

Edit:
I'm also unsure how to use sp_gold() to check what to do next as someone mentioned before. There are many lines here. Should do the checking after each one? That only seems logical, but it would be
July 31st 2018, 12:35 PM
spike.gif
SlipDink
Peasant He/Him United States bloop rumble
2nd generation. No easy way to be free. 
@toof:

But when I talk to him, the entire script attached to him stops working. The conversation doesn't even start. Is this a limitation to the engine, or is there a workaround?

To quote the DINKC Reference v3.1 text file:
The other use of wait() pertains to the fact that the while the dink engine
tries to do many things at once, that is just an illusion. Modern computers
can run huge numbers of instructions per second, but still only one at a time.
Operating systems such as Windows have very sophisticated methods (not all of
them successful...) of making all running programs "take turns" using the CPU.
Within the dink engine, the strategy is more straightforward. Once it starts
running a script, for example, that's all it does -- until the script either
ends or it runs a command that releases the dink engine temporarily to turn
its attention to other tasks. wait() is most important of these commands.

So any wait(), even a wait(1), makes a script "yield the floor" to other
active scripts to allow them time to finish or at least get to their own
wait() points before this script is resumed. See "Part 6 - Overview of
Script Execution", for a discussion of why this is an important trick to
know and understand.]


Below is my version of your script fragment. A quarter of a second is not long for a human wait; but it is practically an eternity for DinkC and most other languages. You could probably get away with a much smaller wait, but I like to make any wait()s within loops as large as is practical, to give the computer a little more time to get other things done.

void main(void)
{
	int &rand;
loop:
	wait(250);
	&rand = random(2,1);
	if(&rand == 1)
	{
		//conversation with other npcs, using say_stop_npc();
	}
	//etc
	goto loop;
}

void talk(void)
{
	//say_stop() and the rest
}


Two other points are:
#1 You have an infinite loop in your code at present. While it should be true that the loop will be terminated when Dink moves to a screen not associated with the script, the code as it is presently written will continually repeat the say_stop_npc(); conversation. You may want to change that.
#2 There are more recent versions of the DINKC help file including a 4.0 version of the DinkC Reference available on the DN as a part of a package that includes other Dink related software, but I always look in the 3.1 text file first. I recommend you make sure to read "Part 6 - Overview of Script Execution" of the 3.1 text file soon.