Help - A slightly more complicated cutscene.

Started by Meowster, Thu 28/08/2003 20:26:09

Previous topic - Next topic

Meowster

I thought this belonged in the technical rather than beginners forum, since it's probably gonna be a hella scripting. Anyway, here's the problem.

I can do a lot of stuff with AGS, and cutscenes involving talking/walking/etc.,. Here's the problem: Programming isn't my forte, so I really need somebody to really help me with this one. You can catch me on AIM as YufsterChan, or MSN as Yufster@Hotmail.com

PROBLEM:
Okay, the character has to complete four small tasks, which are, in no particular order:

1.sabotage something
2.sabotage something else
3. find an item
4. announce that he's ready to compete in the race

Sounds a muddle but I don't want to give everything away. Anyway, there's a sack race, and all the three contestants need to jump together, at the same time, across the screen. Halfway across I need to run animations of the other two contestants falling over and the main character jumping on ahead gleefully.

I don't know how to run the animation of the characters falling over in mid-run (I have the animation complete, but when I tried to run it I suddenly realised that the character would just keep moving, with this amusing gait that I like to call "Slaptooth") Anyway, I figure I must not know something. Also, how do I make the dialogue option (I'm ready to race) available AFTER he's completed all THREE tasks?

SO.....

1. How do I run the animation of the characters falling over in mid-run
2 .How do I make the dialogue option to run this cutscene only available AFTER the three tasks are completed?


As a seperate question, how do I run a script from within a dialogue? It's driving me insane. I tried to figure it out from the demo game but it confused me even more.

MrColossal

well if you aren't good with code i'll try and make this as simplified as i can

maybe someone else has a better idea

let's say you want sackracer1 to move across the screen but trip when he gets to the middle of the screen.

set up in the top of the room script:

int sackracermove;

and then in start the guy moving:

MoveCharacter(sackracer1, 320,100);

he'll move across the screen all the way to the x coordinate 320

so then you should be able to set up in the repeatedly execute:

if ((character[sackracer1].x > 160)&&(sackracermove==0)){    // if he's past the middle of the screen
 sackracermove==1;                                                                   // set sackracermove to 0
 StopMoving(sackracer1);                                                           // stop him from moving
 SetCharacterView(sackracer1, whatever the view is);             // Set his view
 AnimateCharacter(blah blah.);                                                  //animate him
}

what SHOULD happen is that when he passes the center of the screen he will stop moving and animate

if you don't know the && means and, so he has to be passed the center of the screen and sackracermove  has to be set to 0 for this to happen, the reason for this is that he would keep animating over and over again cause he was passed the center of the screen, so we change sackracermove to 1 so that the && clause is now not met.

at least that SHOULD happen, make sense?

question 2: set up another int called i dunno godialogue; and each time you complete a task add a 1 to it.

then in the repeatedly execute do a bit of code that checks that int and if it equals 3 then turn on the dialogue

if (godialogue==3){
SetDialogOption(blah blah blah);
}

and now that dialogue option will be on.if you want it to just turn on once and never again then add in:

if (godialogue==3){
SetDialogOption(blah blah blah);
godialogue=4;
}

now it will only turn on once, understand?

and to run a script in a dialogue paste this into your global script:

 function dialog_request (int xvalue) {
   // your code here
 }

straight out of the manual... let's say you have a run-script 1 in your conversation

add in an if:

function dialog_request (int xvalue) {

if (xvalue==1){
add some code
}

}

and that's it. it will run whatever is in that if and then return to the conversation.

if you want to add more scripts later just create another if and change the xvalue number

make any sense?

eric
"This must be a good time to live in, since Eric bothers to stay here at all"-CJ also: ACHTUNG FRANZ!

MrColossal

"This must be a good time to live in, since Eric bothers to stay here at all"-CJ also: ACHTUNG FRANZ!

Meowster

Yeah, see, I got it... but here's the thing...

I don't understand what I'm doing wrong. I set it up, the game runs fine... but when he gets the two items, (each time I add 1 to INT THREETASKS...) it doesn't turn on that dialogue option. I must be doing something really stupidly wrong somewhere. Here's what I have.



function repeatedly_execute(int threetasks) {
if (threetasks==2){
SetDialogOption(10,5,0);
}


Then, I have this at the very top of the room script:


// room script file
int threetasks;



Then, every time Ian picks up/does one of the things he's supposed to, I have...


if (threetasks <3) {
   threetasks += 1;
 }


Which I changed to

threetasks += 1;

Which also didn't work.

I don't get error messages, it just doesn't seem to add anything to int threetasks :(
I checked that the dialogue option I was specifying was a real dialogue option and everything, that I didn't get it mixed up with another conversation. I must be not understanding part of the scripting. Help, before I lie!





Archangel (aka SoupDragon)

I already said this in #ags, but I'll post it here for the sake of posterity...

instead of
if (threetasks <3) {
threetasks += 1;
}

just have
if(threetasks < 3){
threetasks += 1
}
else{
SetDialogOption(10,5,0);
}

and delete that bit in repeatedlyexecute, since it's not doing anything.

RickJ

Ok,  I'll take a shot at this...

First let me give you a general explanation of what's going on.  Forgive me if I explain stuff you already know.  

When AGS executes a script command nothing happens on the screen until after the script is complete.  The script command merely passes data to the engine which actually changes and moves things around on the screen.  So if the character EGO was initially located at 0,0 and you did the following in a script the character would not move at all.  

  MoveCharacter[EGO,  0, 0];
  MoveCharacter[EGO,  60, 0];
  MoveCharacter[EGO, 160, 100];
  MoveCharacter[EGO, 100, 160];
  MoveCharacter[EGO,  0, 0];

This is beacuse his original position was 0,0 before the script executed and after the script executed his requested position is 0,0 so there is nothing for the engine to do.

To overcome this AGS provides "blocking" instructions that "block" the script until the requested action is completed by the engine.  In other words when a "blocking" command is executed, further instructions in the script are not immediately execute.  Rather execution is returned to the game engine, which sees and executes the request.  When the request is complete the script is released and the next command is executed.  

The problem with using blocking commands is that once a room script is blocked you can't do anything else until the current action is completed.  This fine when you are moving the PC around but inadequate if you are moving NPCs around.  The MoveCharacterPath() command was introduced to get around this problem.  

So here is my suggestion, it's not all that different from what some of the others have suggested.  


// Room Script

int racer1_state = 0;
int racer2_state = 0;

function do_racer1()
{
  if (racer1_state==0) {
     MoveCharacterPath(....);
     MoveCharacterPath(....);
     MoveCharacterPath(....);
      :
     MoveCharacterPath(....);
     racer1_state++;              // add 1 to state
  }
  else if  (racer1_state==1) {
     if (!character[...].walking) {
        racer1_state++;        
     }
  }
  else if  (racer1_state==2) {
     SetCharacterView(...);
     AnimateCharacter(...);
     racer1_state++;        
  }
  else if  (racer1_state==3) {
     if (!character[...].animating)  {
        ReleaseCharacterView(EGO);    
        racer1_state++;        
     }
  }
  else if  (racer1_state==4) {
     MoveCharacterPath(....);
     MoveCharacterPath(....);
     MoveCharacterPath(....);
      :
     MoveCharacterPath(....);
     racer1_state++;        
  }
  else if  (racer1_state==5) {
     if (!character[...].walking) {
        racer1_state++;        
     }
  }
  else if  (racer1_state==6) {
      // do something at end of race
     racer1_state++;        
  }
}

function do_racer2()
{
  // Same as code in do_racer1()
}


function room_x()
{
  // Room script's repeatedly execute event handler

  do_racer1();
  do_racer2();
}

Fill in the "..."s with your specific character id's, postions, views, etc.   Try it and let me know what happens.

Cheers
Rickj



SSH

#6
Also, is "threetasks" declared as a global? If not, you might just be adding 1 to 0 all the time?

Come to think of it, are you using "threetasks" as a graphical variable? in other words, did you initialise it using the GUI rather then in a script somewhere? If so,m you have to use Get/SetGrahicalVariable in the scripts instead of just myvar = 123;

If you want, you can send me the script dump or the game and I can try and debug it?
12

SMF spam blocked by CleanTalk