Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - edmundito

#61
Another recommendation is that you may need to not use sql db to do this but instead export all the data in JSON; this is actually what most commercial games with lots of data do. Then with the Lua plugin you may be able to load, parse and organize the data.
#62
Need help? I started a chat room on Discord:
https://discord.gg/vmuCyWX

(also updated the main post with the chat link.)
#63
Depends on what you'd like to do. If you want to push the GUI so that it doesn't overlap the end of the room, once you get the position, you can ensure that it is never placed beyond the screen:

Code: ags

// Assuming that the target X position of the GUI is so that it's centered on the character:
// character screen X - half GUI width
int targetX = (cYourCharacter.X - GetViewportX()) - (gYourGui.Width / 2);

// If the GUI ends over the screen width, then set it to the screen with - the gui width.
if (targetX + gYourGui.Width > System.ScreenWidth) {
  targetX = System.ScreenWidth - gYourGui.Width;
}
// The gui is less than the screen width, set it to 0.
if (targetX < 0) {
  targetX = 0;
}
gYourGui.X = targetX;

// Another option is to use the ClampInt function that comes in the tween 2 module:
int targetX = (cYourCharacter.X - GetViewportX()) - (gYourGui.Width / 2);
targetX = TweenMaths.ClampInt(targetX, 0, System.ScreenWidth - gYourGui.Width);
gYourGui.X = targetX;


noloopcheck is there because my function does the dangerous thing of having a while loop that waits indefinitely until the user clicks. Probably not necessary to use because the limit is pretty high.
#64
Hi, this is quite a challenging question! It's not an easy thing to create, or to solve without really tryingg to do it, but here are some tips on how to get you there:

1. Think of the keyframes: Where does it start, where does it end?
2. Figure out how to code the end first, code a function that displays simple box on top of the character that roughly achieves what you are trying to do, without animation.
3. Try to think about how to resize it to fit the end result. Write a function that can resize the box when you call your custom speech function
4. Once you create that resized box, save all the data, rewind it to the start position and play the Tweens.

I followed a similar approach with Display2 in the Tween Module demo. If you download the source code and run the game in AGS, you may be able to see it by calling:

Code: ags
Display2('Hello world!');


https://raw.githubusercontent.com/edmundito/ags-tween/master/Tween/Display2.asc

Notice that the first call a function called _reflow, this is the function that resizes the window to fit the right size. You might be able to get some ideas on how to resize your box.
Finally, the rest of the code just rewinds to the start position, plays back the tween, controls the wait time, and then ends the tween.
#65
Quote from: Crimson Wizard on Mon 02/05/2016 01:00:12
Edmundito, daneeca just replied 1 post above:

Quote from: daneeca on Sun 24/04/2016 15:37:27
Yes, that was the problem. It's working now. This module is awesome! :)
Thanks again and sorry for my clumsiness.

Apparently there was simply a global variable of that name.

Oooh, totally missed that Page 2!
#66
Unfortunately I can't make it this year regardless of it's held. But Sweden sounds good, though!
#67
Quote from: daneeca on Thu 21/04/2016 22:49:10
I have the Smooth Scrolling & Parallax module and a global variable named "max".
So, maybe this is the problem. If I rename the max global variable it probably will work. I'll try it tomorrow and report the results.

Thanks for the help!

daneeca, Were you able to test this?
#68
Quote from: daneeca on Thu 21/04/2016 18:54:09
Hi!
I wanted to try it, but I got an error message:
"Tween.asc(212): Error (line 212): 'max' is a global var; cannot use as name for local"

Maybe It's not working with AGS 3.4.0.6? :/

Hi! I have actually not tested it on 3.4 yet, but maybe I should. I'll take a look at it this weekend. I've created a bug report in:
https://github.com/edmundito/ags-tween/issues/7

If anyone else is testing in 3.4.x, please let me know what works for you and what doesn't. If you'd like to see some new tween supported for 3.4 features please let me know as well.
#69
Quote from: Crimson Wizard on Sat 12/03/2016 15:36:24
Please, we had this discussion many times. I am against putting this branch into our main repository. Two main reasons are:
1) it adds precompiled library binaries to repository, and we are against that (also, are these modified and are there sources of these?).
2) AFAIK it hacks SDL code into Allegro to make it run on mac, thus increasing general mess.
It makes it work and so serves its purpose, but it is not a clean way to do things.


Of course, separating OSX changes into a clean branch would make things easier to analyse. Also, so far it is the only up-to-date OSX version that actually works, so it would be silly to reject one. But I would suggest to keep this version in a separate repository for now until the issues I mentioned are resolved.


I also found my own suggestion made several months ago:
Quote from: Crimson Wizard on Mon 05/10/2015 09:27:33
E: Since we now have an automation server, one of the options could be making a pull request that combines Janet's Humble Bundle port (not their pull request, but the most up-to-date version, I think this: https://github.com/JanetGilbert/ags/commits/humble-ports) and our current master.
The pull request will never be meant for actual merging (at least not until removing precompiled binaries), but it could serve for automatic building working OSX port.

Great points, I think your suggestion great and it's a good step to take. I would agree that having those binaries without the modified source code is dirty, but even if we can get to the point that there's an experimental "acmac" build for 3.3 and 3.4 that remains forked from the main repo would be a big accomplishment.
#70
Crimson Wizard, merging develop-3.3.5 did indeed fix the mouse issues. This is looking very promising. I have pushed the changes into my own fork. Here is a comparison:

https://github.com/adventuregamestudio/ags/compare/develop-3.3.5...edmundito:edmundito/osx-develop-3.3.5-clean?expand=1

To get it into the main source code, probably need to do the following:

- Pick only the os x changes (over linux and wadjet eye games specific) into a clean branch
- Encapsulate the mac modifications as #if defined (MAC_VERSION)
- Merge/rebase to develop-3.3.5 and resolve conflicts
- Fix the make files (right now I am hacking one of the game projects to make a build)
- Push and create a PR for adventuregamestudio/ags
#71
I had some free time, so I tried merging and resolving a few conflicts from the official v3.3.5.1 tag to JanetC's branch. Note that I am no expert in the AGS Engine source.

The result looked promising at a first glance. I was able to run a game. I think some of the more advanced animations seemed slow compared to the windows version.

There were a couple of major issues that I disabled in the meantime:

- The entire mouse handler has been rewritten; the way to get the mouse position is very different. This definitely causes some major cursor problem in full screen, and the mouse does not move correctly at all. In windowed mode, I saw the mouse reset to 0,0 when moving the cursor to the top outside the window.
https://github.com/JanetGilbert/ags/blob/humble-ports/Engine/device/mousew32.cpp#L99
https://github.com/adventuregamestudio/ags/blob/v.3.3.5.1/Engine/device/mousew32.cpp#L103

The window mode issue can be fixed by switching this variable to 1, but the full screen problems still prevail.
https://github.com/adventuregamestudio/ags/blob/v.3.3.5.1/Engine/device/mousew32.cpp#L62

- There's some hack involving reading the config file in the AGSMac. The way the INI file is loaded has changed as well, but may not be too much of a hard fix. I am not sure why was added:
https://github.com/JanetGilbert/ags/blob/humble-ports/Engine/platform/osx/acplmac.cpp#L132

- One issue I also foresee is that the graphics settings have changed from 3.2 to 3.3 and may affect the OS X migration more than expected and may cause more issues than anticipated.
#72
Really enjoyed it. I liked the use of color and sound, and I really like the level of detail in the UI. The writing and the theme was good, looked well researched.

I was also really creeped out, in a good way, as the rooms changed when I returned to them :-) I got into a few of the outcomes, but what I was really trying to get into were the Pagan solutions. How many different outcomes or solutions are there? How do I figure out the pagan parts?
#73
Quote from: Monsieur OUXX on Fri 18/12/2015 18:03:28
Suggestion for next version:

Make it easier to bind together some tweens (one for X, and one for Y, and why not one for altitude, etc.), based on a shared movement speed.

Let me explain what I mean:

Imagine you have a room Object that you want to move at a given speed. Then you can simply use Object.TweenPosition along with TimingType == eTweenSpeed. The module takes charge of calculating the duration matching that speed, and then updates both X and Y automatically with the appropriate ratio applied to each of them (namely: cos, and sin).

However, now, imagine you want to do the same with your very own abstract Tween object, that you will use for drawing onto surfaces. Very much the same as you do in the "Indy map example" in the first post. Then it's a pain to calculate the duration and the ratios by hand. You didn't have to do it in your example because you simply set the same duration (3.0) to both X and Y.

It's not too hard to do it, but if you created a class for an abstract (X,Y) tween (not relying on an actual AGS Object or Character or whatnot) that would be really cool...

Hey, interesting idea, glad to see that some of the new fancy features are getting pushed to the limit.

I was wondering two things:

Is this specific to creating custom Tweens or for other types of combinations as well? Could you give me some examples of things you were trying to do with speed that the module did not support?

Can tell me more about "altitude" and how it relates in AGS?
#74
Quote from: ollj on Sun 19/07/2015 14:56:01
The GUI."resize" tween pivots to the top left ot the GUI, and i assume thats the same for dynamicsprites...

having a function that somehow manages to set the scaling pivot, the point of the image that doesnt move when resizing, percentually with a float. That is whats missing for me.

Oh yeah, that's a fairly advanced issue that maybe I can look into including into the module. I've added it as an idea in the github issue tracker:
https://github.com/edmundito/ags-tween/issues/3

In the meantime, here is a function that can resize the GUI with the pivot, you can update it to fit the object that you need:

Add this to your Global Script or a Module Script:
Code: ags
int TweenSizeFromPivot(this GUI*, Pivot pivot, float timing, int toWidth, int toHeight, TweenEasingType easingType, TweenStyle style, float startDelay, TweenTimingType timingType) {
  int toX = this.X;
  int toY = this.Y;

  if (pivot == ePivotTopCenter || pivot == ePivotMiddleCenter || pivot == ePivotBottomCenter) {
    toX += (this.Width - toWidth) / 2;
  } else if (pivot == ePivotTopRight || pivot == ePivotMiddleRight || pivot == ePivotBottomRight) {
    toX += (this.Width - toWidth);
  }
  
  if (pivot == ePivotMiddleLeft || pivot == ePivotMiddleCenter || pivot == ePivotMiddleRight) {
    toY += (this.Height - toHeight) / 2;
  } else if (pivot == ePivotBottomLeft || pivot == ePivotBottomCenter || pivot == ePivotBottomRight) {
    toY += (this.Height - toHeight);
  }
  
  int sizeDuration = this.TweenSize(timing, toWidth, toHeight, easingType, eNoBlockTween, startDelay, timingType);
  int positionDuration = this.TweenPosition(timing, toX, toY, easingType, eNoBlockTween, startDelay, timingType);
  if (style == eBlockTween) {
    WaitForLongest(sizeDuration, positionDuration);
  }
}


Add this to your Global Script Header or a Module Header:
Code: ags
enum Pivot {
    ePivotTopLeft,
    ePivotTopCenter,
    ePivotTopRight,
    ePivotMiddleLeft,
    ePivotMiddleCenter,
    ePivotMiddleRight,
    ePivotBottomLeft,
    ePivotBottomCenter,
    ePivotBottomRight
};

import int TweenSizeFromPivot(this GUI*, Pivot pivot, float timing, int toWidth, int toHeight, TweenEasingType easingType=Tween_EASING_TYPE_GUI, TweenStyle style=Tween_STYLE_GUI, float startDelay=Tween_START_DELAY_GUI, TweenTimingType timingType=Tween_TIMING_GUI);


Simple Usage:
Code: ags
gIconbar.TweenSizeFromPivot(eBottomRight, 0.5, 160, 120);
#75
Quick update: I've set up a public Skype chat if you'd like to have some live support or chat about tween module techniques:

Tween Module Skype Chat Group: https://join.skype.com/CsrRAc17CJIb

(Also updated the main post with this info!)
#76
2.0.1 now available with a minor fix related to Character, Object, or GUI FadeIn FadeOut tweens. Thanks to Blackthorne!
#77
Latest Version is 2.2.0 - See the Tween 2.2.0 thread for more details!

The AGS Tween Module allows you to programmatically interpolate many of the AGS properties (objects, characters, regions, viewport, audio, gui, gui controls, etc.) over time in amazing ways. The term tween comes from "inbetweening". It's typically used in Adobe Flash to indicate interpolation of an object from one keyframe to another.

Instead of depending on while loops everywhere in your code:
Code: ags

while (gIconbar.Y > -gIconbar.Height) {
  gIconbar.Y = gIconbar.Y - 1;
  Wait(1);
}


You can do this:
Code: ags

gIconbar.TweenY(0.5, -gIconbar.Height, eEaseInBackTween);


Notable games using the tween module include: A Golden Wake, Primordia, the Ben Jordan series, and Gemini Rue.

---

Tween 2.x is a huge upgrade from Tween 1.x. It is closer to the vision I had when I first started working on the first Tween module while still keeping the simplicity of the original.

Major changes include:

New Easing Functions

The new easing functions are based on common easing functions used by other tween modules. These include elastic, bouncing, backing out, etc.
You can see a demo of these at http://easings.net.

Stop Individual Tweens

You can now stop individual tweens:

Code: ags
cEgo.TweenPosition(2.0, 100, 100, eEaseLinearTween, eReverseRepeatTween);

// ... Later:
cEgo.StopTweenPosition();


Tween by SPEED

You can tween ANYTHING by speed instead of seconds as well. This allows you to move objects at a constant speed regardless of where they are.

Start Delay

You can delay the start of any tween allowing you to create interesting effects.

Convenient fade out and fade in tween functions

Code: ags
gIconbar.TweenFadeOut(0.5);


Custom Tweens

For the advanced users who like to have control, you can also create your own custom tweens that take advantage of the module's easing and timing functions. This also allows you to create tweens for drawing surfaces.

Code: ags

function TweenIndyMapLine(int fromX, int fromY, int toX, int toY) {
  Tween.IncreaseGameSpeed();
 
  Tween myTweenX;
  Tween myTweenY;
  myTweenX.Init(3.0, fromX, toX);
  myTweenY.Init(3.0, fromY, toY);
  int previousX = FloatToInt(myTweenX.FromValue);
  int previousY = FloatToInt(myTweenY.FromValue);
  int drawColor = Game.GetColorFromRGB(255, 0, 0);
  
  while (myTweenX.IsPlaying() || myTweenY.IsPlaying()) {
    myTweenX.Update();
    myTweenY.Update();
   
    DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
    surface.DrawingColor = drawColor;
    surface.DrawLine(previousX, previousY, myTweenX.Value, myTweenY.Value, 3);
    surface.Release();
    
    previousX = myTweenX.Value;
    previousY = myTweenY.Value;
    
    Wait(1);
  }
   
  Tween.RestoreGameSpeed();
}


No longer compatible with AGS 2.x!

If you would like to use the tween module with an AGS 2 game, then get the Tween 1.x module.

---

Download from:
https://github.com/edmundito/ags-tween/releases/tag/v2.1.0

Documentation:
http://ags-tween.readthedocs.io/en/v2.1.0/

Support Chat:
https://discord.gg/vmuCyWX

Issues and Feature Planning:
https://github.com/edmundito/ags-tween/issues

Special Thanks to:
Tzachs for expanding the original module to support most of the properties in AGS, Grundislav and Dualnames for promoting and creating very inspiring work with the original module, jwalts37 who I met in person at GDC 2014 and told me how much he liked the module, Vince Twelve for showing me some advanced code that was the inspiration for Tween 2's startDelay, Calin Leafshade for giving me more insight into scripting best practices, and everyone in the forum for reporting problems and making games with this.
#78
Here's the script where Indy gives the grail back to the knight:

Code: ags

Script# 203
[0000] cutscene([1]);
[0005] print(10,[Text("I give you my thanks." + wait() + "I see you indeed have the heart of a true Knight.")]);
[0051] WaitForMessage();
[0052] if (!Bit[1497]) {
[0057]   startScript(125,[69,100]);
[0060]   VAR_RESULT = getRandomNr(1);
[0064]   if (VAR_RESULT) {
[0069]     print(10,[Text("You should have seen the wreck this place was in" + newline() + "after the last guys left.")]);
[00B8]   } else {
[00BB]     print(10,[Text("Your nobility has kept the Grail safe, and this" + newline() + "Temple unspoiled." + wait() + "May you find your true path.")]);
[011F]   }
[011F]   setBoxFlags(6,0);
[0122]   setBoxFlags(7,0);
[0125] } else {
[0128]   startScript(125,[70,75]);
[0131]   VAR_RESULT = getRandomNr(1);
[0135]   if (VAR_RESULT) {
[013A]     print(10,[Text("Of course, I'll be picking this place up for years^")]);
[0171]   } else {
[0174]     print(10,[Text("But now you must go.  I fear I have a Herculean" + newline() + "task yet before me." + wait() + "Now where was that broom?")]);
[01D7]   }
[01D7]   setBoxFlags(17,0);
[01DA]   setBoxFlags(18,0);
[01DD] }
[01DD] WaitForMessage();
[01DE] walkActorToObject(10,862);
[01E2] waitForActor(10);
[01E4] putActorInRoom(10,0);
[01E7] setBoxFlags(6,128);
[01EA] setBoxFlags(7,128);
[01ED] setBoxFlags(17,128);
[01F0] setBoxFlags(18,128);
[01F3] if (!Bit[1497]) {
[01F8]   startScript(68,[1,518,113,245],R);
[0207]   startScript(68,[3,575,112,244],R);
[0216]   waitForActor(1);
[0218]   print(3,[Text("We could have taken the Grail from this place." + wait() + "It could have been ours, Indy.")]);
[026A]   WaitForMessage();
[026B]   startScript(68,[1,138,111,244],R);
[027A]   startScript(68,[3,163,118,244],R);
[0289]   VAR_RESULT = getRandomNr(1);
[028D]   if (VAR_RESULT) {
[0292]     print(1,[Text("Don't bet on it.")]);
[02A6]   } else {
[02A9]     print(1,[Text("That may be your game plan, Elsa, but" + newline() + "I won't play it that way.")]);
[02ED]   }
[02ED] } else {
[02F0]   startScript(68,[1,138,111,244],R);
[02FF] }
[02FF] waitForActor(1);
[0301] waitForActor(3);
[0303] Var[99] = 1;
[0308] Var[100] = VAR_CAMERA_POS_X;
[030D] breakHere();
[030E] unless (VAR_CAMERA_POS_X == Var[100]) goto 0308;
[0315] endCutscene();
[0316] if (Var[99]) {
[031B]   startScript(65,[Var[99]]);
[0321] }
[0321] stopObjectCode();
END


Sidenote: SCUMM script didn't look like this at all. This is ScummVM interpreting names for things based on what unreadble chunks of data were supposed to do (the variable names are lost, for example.). Ron Gilbert is the only person who described what it looked like in presentations and in this article: http://www.pagetable.com/?p=614
#79
Based on what was mentioned in the first post ("Well this is just grand! We meet a living veteran of the Crusades, steal his Grail, and then completely destroy his temple! All in the name of Archaeology? I will never do anything like this again."), the script in question is in the global script in room 82. The line is there, but seems completely random. I've attached the script.

Code: ags

[0000] cutscene([1]);
[0005] Var[100] = VAR_CAMERA_POS_X;
[000A] breakHere();
[000B] unless (VAR_CAMERA_POS_X == Var[100]) goto 0005;
[0012] if (Var[99] == 1) {
[0019]   print(2,[Text("That was a just and noble thing you did, Junior.")]);
[004D]   WaitForMessage();
[004E]   print(1,[Text("Don't call me Junior!")]);
[0067]   WaitForMessage();
[0068]   print(4,[Text("What is all this Junior talk?")]);
[0089]   WaitForMessage();
[008A]   print(2,[Text("That's his name:" + wait() + "Henry Jones, Jr.")]);
[00B0]   WaitForMessage();
[00B1]   print(1,[Text("I like Indiana.")]);
[00C4]   WaitForMessage();
[00C5]   print(2,[Text("We named the DOG Indiana!" + wait() + "We named YOU Henry, Jr.")]);
[00FB]   WaitForMessage();
[00FC]   print(4,[Text("Come to think of it, my father had a cat named `Marcus`.")]);
[0138]   WaitForMessage();
[0139]   VAR_RESULT = getActorRoom(3);
[013D]   if (VAR_RESULT == 82) {
[0144]     print(3,[Text("Hmm.  Wasn't my father's secretary named `Elsa`?")]);
[0178]     WaitForMessage();
[0179]   }
[0179]   print(2,[Text("Enough!  Let's go home." + wait() + "I think I'll start a Dead Sea Scrolls Diary.")]);
[01C2]   WaitForMessage();
[01C3]   print(4,[Text("Everybody, follow me, I know the way!")]);
[01EC]   delay(60);
[01F0]   panCameraTo(160);
[01F3]   WaitForMessage();
[01F4]   breakHere();
[01F5]   unless (VAR_CAMERA_POS_X == 160) goto 01F4;
[01FC]   walkActorTo(4,400,120);
[0202]   breakHere();
[0203]   breakHere();
[0204]   startScript(56,[4,1],R);
[020D]   startScript(56,[1,2],R);
[0216]   VAR_RESULT = getActorRoom(3);
[021A]   if (VAR_RESULT == 82) {
[0221]     startScript(56,[2,3],R);
[022A]   }
[022A]   waitForActor(4);
[022C]   delay(120);
[0230]   print(4,[Text("No, that's not right.")]);
[0249]   WaitForMessage();
[024A]   walkActorToObject(4,861);
[024E]   waitForActor(4);
[0250]   stopScript(56);
[0252] } else if (Var[99] == 2) {
[025C]   VAR_EGO = 2;
[0261]   actorFollowCamera(VAR_EGO);
[0264]   breakHere();
[0265]   unless (VAR_CAMERA_POS_X <= 160) goto 0264;
[026C]   print(2,[Text("Junior!  Why didn't you listen!")]);
[028F]   WaitForMessage();
[0290]   print(255,[Color(14),Text("Don't call me JUUUUNIOOOOOooooooorrrrr^")]);
[02BD]   WaitForMessage();
[02BE]   delay(30);
[02C2] } else if (Var[99] == 3) {
[02CC]   print(3,[Text("Oh, Indy!" + wait() + "If only you'd let me try, I could have taken the Grail" + newline() + "for the two of us!")]);
[0325]   WaitForMessage();
[0326]   VAR_RESULT = getRandomNr(1);
[032A]   if (VAR_RESULT) {
[032F]     print(2,[Text("The Grail is not a prize to be won." + wait() + "Junior knows that now.")]);
[036E]     WaitForMessage();
[036F]   } else {
[0372]     animateCostume(4,4);
[0375]     animateCostume(2,4);
[0378]     print(255,[Color(10),Text("Don't bet on it. " + keepText())]);
[0391]     print(255,[Color(7),Text("Don't bet on it.                     ")]);
[03BC]     WaitForMessage();
[03BD]     animateCostume(4,5);
[03C0]     animateCostume(2,5);
[03C3]   }
[03C3]   delay(30);
[03C7] } else if (Var[99] == 4) {
[03D1]   startScript(125,[71,50]);
[03DA]   VAR_RESULT = getRandomNr(1);
[03DE]   if (VAR_RESULT) {
[03E3]     print(2,[Text("Well this is just grand^" + wait() + "We meet a living veteran of the Crusades, steal his Grail," + wait() + "and then completely destroy his temple!" + wait() + "All in the name of Archaeology?" + wait() + "I will never do anything like this again.")]);
[04B0]     WaitForMessage();
[04B1]     print(1,[Text("Hey Dad, I think the Knight muttered something about his" + newline() + "friend, Ponce, who's living in Florida!")]);
[0516]     WaitForMessage();
[0517]     print(2,[Text("Let's go find him!!!")]);
[052F]   } else {
[0532]     print(2,[Text("Son, I'm proud of you." + wait() + "The quest for the Grail is the quest for the sacred part" + newline() + "in each of us." + wait() + "I can see that you found something more than just" + newline() + "a prize to be won.")]);
[05DD]     WaitForMessage();
[05DE]     print(1,[Text("And what did you find, Dad?")]);
[05FD]     WaitForMessage();
[05FE]     animateCostume(2,250);
[0601]     delay(60);
[0605]     print(2,[Text("Enlightenment.")]);
[0617]     WaitForMessage();
[0618]     animateCostume(2,249);
[061B]     print(2,[Text("Let's go, son.")]);
[062D]   }
[062D]   WaitForMessage();
[062E]   walkActorToObject(2,861);
[0632]   breakHere();
[0633]   breakHere();
[0634]   breakHere();
[0635]   breakHere();
[0636]   walkActorToObject(1,861);
[063A]   waitForActor(2);
[063C]   /* goto 063F; */
[063F] }
[063F] loadRoom(94);
[0641] delay(36000);
[0645] goto 0641;
[0648] endCutscene();
[0649] stopObjectCode();
END


Seems like it's a ~50% chance if you can get to the right ending sequence.

Here's another script in the room that sets Var[99] (the end condition)
Code: ags

[0000] breakHere();
[0001] VAR_RESULT = getActorX(1);
[0005] unless (VAR_RESULT < 300) goto 0000;
[000C] VAR_RESULT = getObjectOwner(873);
[0011] if (VAR_RESULT == 1) {
[0018]   cutscene([1]);
[001D]   startSound(50);
[001F]   animateCostume(1,255);
[0022]   delay(60);
[0026]   animateCostume(1,246);
[0029]   delay(60);
[002D]   Resource.loadCostume(66);
[0030]   ShakeOn();
[0036]   delay(30);
[003A]   drawObject(874,255,255);
[0041]   startSound(6);
[0043]   delay(10);
[0047]   drawObject(875,255,255);
[004E]   startSound(6);
[0050]   delay(30);
[0054]   ActorOps(1,[Costume(66)]);
[0059]   animateCostume(1,6);
[005C]   Local[0] = 1;
[0061]   breakHere();
[0062]   Local[0]++;
[0065]   unless (Local[0] > 20) goto 0061;
[006C]   delay(30);
[0070]   VAR_TIMER_NEXT = 20;
[0075]   setState(875,0);
[0079]   setState(874,1);
[007D]   startSound(6);
[007F]   breakHere();
[0080]   setState(874,0);
[0084]   startSound(6);
[0086]   VAR_TIMER_NEXT = 6;
[008B]   delay(60);
[008F]   ShakeOff();
[0095]   delay(60);
[0099]   stopSound(50);
[009B]   VAR_RESULT = getActorRoom(3);
[009F]   if (VAR_RESULT == 82) {
[00A6]     startScript(206,[3]);
[00AC]     startScript(206,[10]);
[00B2]     VAR_EGO = 3;
[00B7]     actorFollowCamera(VAR_EGO);
[00BA]     Var[100] = VAR_CAMERA_POS_X;
[00BF]     breakHere();
[00C0]     unless (VAR_CAMERA_POS_X == Var[100]) goto 00BA;
[00C7]     VAR_RESULT = getRandomNr(1);
[00CB]     if (VAR_RESULT) {
[00D0]       print(3,[Text("I could have gotten the Grail out of here.")]);
[00FE]       WaitForMessage();
[00FF]       print(10,[Text("Don't bet on it.")]);
[0113]     } else {
[0116]       print(3,[Text("Indiana.  You should have let me take the Grail.")]);
[014A]       WaitForMessage();
[014B]       print(10,[Text("I think his fate was in^")]);
[0167]       WaitForMessage();
[0168]       animateCostume(10,250);
[016B]       breakHere();
[016C]       breakHere();
[016D]       print(10,[Text("^other hands.")]);
[017E]     }
[017E]     WaitForMessage();
[017F]     if (Bit[1497]) {
[0184]       setBoxFlags(17,0);
[0187]       setBoxFlags(18,0);
[018A]     } else {
[018D]       setBoxFlags(6,0);
[0190]       setBoxFlags(7,0);
[0193]     }
[0193]     walkActorToObject(10,862);
[0197]     startScript(68,[3,138,111],R);
[01A3]     waitForActor(3);
[01A5]     Var[99] = 3;
[01AA]   } else {
[01AD]     panCameraTo(0);
[01B0]     Var[100] = VAR_CAMERA_POS_X;
[01B5]     breakHere();
[01B6]     unless (VAR_CAMERA_POS_X == Var[100]) goto 01B0;
[01BD]     VAR_EGO = 2;
[01C2]     actorFollowCamera(VAR_EGO);
[01C5]     Var[99] = 2;
[01CA]   }
[01CA]   Var[100] = VAR_CAMERA_POS_X;
[01CF]   breakHere();
[01D0]   unless (VAR_CAMERA_POS_X == Var[100]) goto 01CA;
[01D7]   endCutscene();
[01D8] } else {
[01DB]   cutscene([1]);
[01E0]   startScript(68,[1,138,111,244],R);
[01EF]   waitForActor(1);
[01F1]   Var[99] = 4;
[01F6]   Var[100] = VAR_CAMERA_POS_X;
[01FB]   breakHere();
[01FC]   unless (VAR_CAMERA_POS_X == Var[100]) goto 01F6;
[0203]   endCutscene();
[0204] }
[0204] if (Var[99]) {
[0209]   startScript(65,[]);
[020C] }
[020C] stopObjectCode();
END
#80
Heh, sorry I'm bumping this up but I was doing a google search on how to do this and stumbled upon your question. (I've been playing Grim Fandango HD recently and I've learned that there's enough tools out there to reverse engineer these games.)

Here's one way to do it:

Download SCUMM Revisited from: http://quick.mixnmojo.com/files/ScummRev2.zip
Open the .LFL files in the INDY directory
Find each node in the tree that is marked as "SC" or "LS" is a script. Click on "File Dump..."
Then clone and build the SCUMM VM tools (here's how you would do it with cygwin or on linux/mac):
Quote
git clone https://github.com/scummvm/scummvm-tools.git
cd scummvm-tools
./configure
make

Then this will create a tool called descumm that decompiles the script

Quote
./descumm -xcn SL.srb

(The -n is for Indy 256. You can figure out which version of SCUMM your game is from at: http://wiki.scummvm.org/index.php/SCUMM/Versions)

You will then see something like this:
Code: ags

Script# 202
delay(600);
VAR_RESULT = getActorX(1);
if (VAR_RESULT == 45) {
  VAR_RESULT = getActorY(1);
  if (VAR_RESULT == 94) {
    cutscene([]);
    animateCostume(1,255);
    print(255,[Color(7),Text("Indy!!!  Hurry up!  Your father is getting worse!!")]);
    delay(20);
    animateCostume(1,244);
    WaitForMessage();
    print(1,[Text("I know Marcus!  I'm hurrying!")]);
    walkActorTo(1,18,96);
    waitForActor(1);
    WaitForMessage();
    delay(20);
    animateCostume(1,245);
    endCutscene();
  }
}
stopObjectCode();
END


(Don't ask me how I just figured out how to do all this.)
SMF spam blocked by CleanTalk