Tunnels are in. Close #30

This commit is contained in:
2019-06-06 21:33:29 -06:00
parent 7692655d71
commit 0a07887579
5 changed files with 119 additions and 18 deletions

View File

@@ -0,0 +1,40 @@
// Based on https://github.com/inkle/ink/blob/01898140be43d29baac70c1cb6544bdb10164209/Documentation/WritingWithInk.md#tunnels-run-sub-stories
// TODO this hack is because we don't have divert arguments yet.
~ var location = ->plains;
-> @location
=== plains
= night_time
The dark grass is soft under your feet.
+ [Sleep]
-> sleep_here -> wake_here -> day_time
= day_time
It is time to move on.
=== wake_here
You wake as the sun rises.
+ [Eat something]
-> eat_something -> @location.day_time
+ [Make a move] -> @location.day_time
=== sleep_here
You lie down and try to close your eyes.
-> monster_attacks ->
Then it is time to sleep.
-> dream ->
// I added these:
= monster_attacks
You get attacked by a monster!
= dream
You dream about even scarier monsters.
=== eat_something
You're out of food! Soon you will starve to death.

View File

@@ -0,0 +1,13 @@
The dark grass is soft under your feet.
* Sleep
> 1:
You lie down and try to close your eyes.
You get attacked by a monster!
Then it is time to sleep.
You dream about even scarier monsters.
You wake as the sun rises.
* Eat something
* Make a move
> 1:
You're out of food! Soon you will starve to death.
It is time to move on.

View File

@@ -10,7 +10,7 @@ enum ExprType {
EOutput(o: Output);
EDivert(target: String);
EDivert(targets: Array<String>);
EThread(target: String);
EKnot(name: String);
EStitch(name: String);

View File

@@ -142,10 +142,10 @@ class Parser {
}
static function divert(buffer: HankBuffer, position: HankBuffer.Position) : ExprType {
buffer.drop('->');
buffer.skipWhitespace();
var tokens = lineTokens(buffer, 1, position, true, true);
return EDivert(tokens[0]);
var line = buffer.takeLine().unwrap();
var targets = [for(t in line.split('->')) t.trim()].slice(1);
return EDivert(targets);
}
static function thread(buffer: HankBuffer, position: HankBuffer.Position) : ExprType {

View File

@@ -101,7 +101,8 @@ class Story {
function storyFork(t: String): Story {
// Everything is the same as when embedding blocks, but a fork uses the same AST as its parent -- simply starting after a hypothetical divert
var story = new Story(random, parser, this.ast, storyTree, nodeScopes, viewCounts, hInterface);
story.parent = Some(this);
// Just trust me that in Tunneling mode, the embedded stories don't need a parent. This is because I was too lazy to disambiguate tunnel mode from embedded mode.
if (embedMode == Thread) story.parent = Some(this);
// trace('story parent: ${story.parent.match(Some(_))}');
story.divertTo(t);
return story;
@@ -224,16 +225,43 @@ class Story {
exprIndex += 1;
hInterface.runEmbeddedHaxe(h, nodeScopes);
return nextFrame();
case EDivert(target):
// Fallback choices simply advance flow using divert syntax
if (target.length == 0) {
// Fallback choices simply advance flow using divert syntax by not specifying a target
case EDivert([""]):
exprIndex += 1;
}
// All other diverts:
else {
divertTo(target);
}
// The most common form of divert is to one other location.
case EDivert([oneTarget]):
divertTo(oneTarget);
return nextFrame();
// Tunneling statements!
case EDivert(targets):
switch (targets.pop()) {
case target if (target != ''):
// If the last target isn't empty, we want to fork the main story to start at that point once the tunnels are done.
// trace('this divert');
divertTo(target);
case '':
exprIndex++;
case null:
throw 'No divert targets!';
}
// Spawn the rest of the forks in tunneling mode
for (target in targets) {
// trace('embedded $target');
var fork = storyFork(target);
// trace(fork != null);
embeddedBlocks.push(fork);
// trace(embeddedBlocks.length);
}
// trace(embeddedBlocks.length);
return nextFrame();
case EThread(target):
// The thread only needs to be added once
exprIndex++;
@@ -410,14 +438,34 @@ class Story {
// trace('diverting to $target');
var newScopes = if (target.startsWith("@")) hInterface.getVariable(target.substr(1)) else resolveNodeInScope(target);
var newScopes = if (target.startsWith("@")) {
var parts = target.split('.');
var root: Array<StoryNode> = hInterface.getVariable(parts[0].substr(1));
if (parts.length > 1) {
var subTarget = parts.slice(1).join('.');
//trace(subTarget);
resolveNodeInScope(subTarget, root);
} else {
root;
};
}
else resolveNodeInScope(target);
// trace('$target is $newScopes');
if (newScopes == null // happens when a divert target variable doesn't exist
|| newScopes.length == 0) // happens when target can't be resolved
throw 'Divert target not found: $target';
var targetIdx = newScopes[0].astIndex;
if (targetIdx == -1) {
throw 'Divert target not found: $target';
}
if (targetIdx == null) {
throw 'Divert target not found: $target';
}
//trace(targetIdx);
// update the expression index
exprIndex = targetIdx;
var target = newScopes[0];