diff --git a/README.md b/README.md
index 74323eb6..97307534 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
![](https://raw.githubusercontent.com/JujuAdams/Chatterbox/master/LOGO.png)
-2.5.1
+2.6.0
Narrative engine for GameMaker by @jujuadams
diff --git a/chatterbox.yyp b/chatterbox.yyp
index 047f6230..06ca00cf 100644
--- a/chatterbox.yyp
+++ b/chatterbox.yyp
@@ -4,6 +4,7 @@
{"id":{"name":"__ChatterboxSystem","path":"scripts/__ChatterboxSystem/__ChatterboxSystem.yy",},"order":6,},
{"id":{"name":"ChatterboxLoadFromBuffer","path":"scripts/ChatterboxLoadFromBuffer/ChatterboxLoadFromBuffer.yy",},"order":3,},
{"id":{"name":"TestCaseWaitFunction","path":"scripts/TestCaseWaitFunction/TestCaseWaitFunction.yy",},"order":31,},
+ {"id":{"name":"oTestCaseFastForward","path":"objects/oTestCaseFastForward/oTestCaseFastForward.yy",},"order":34,},
{"id":{"name":"ChatterboxGetVisited","path":"scripts/ChatterboxGetVisited/ChatterboxGetVisited.yy",},"order":5,},
{"id":{"name":"oTestCaseParsers","path":"objects/oTestCaseParsers/oTestCaseParsers.yy",},"order":26,},
{"id":{"name":"ChatterboxVariablesClearVisitedAll","path":"scripts/ChatterboxVariablesClearVisitedAll/ChatterboxVariablesClearVisitedAll.yy",},"order":6,},
@@ -168,6 +169,7 @@
{"CopyToMask":-1,"filePath":"datafiles","resourceVersion":"1.0","name":"testcase_all_content_string.yarn","resourceType":"GMIncludedFile",},
{"CopyToMask":-1,"filePath":"datafiles","resourceVersion":"1.0","name":"testcase_wait_function.yarn","resourceType":"GMIncludedFile",},
{"CopyToMask":-1,"filePath":"datafiles","resourceVersion":"1.0","name":"testcase_setter_local_scope.yarn","resourceType":"GMIncludedFile",},
+ {"CopyToMask":-1,"filePath":"datafiles","resourceVersion":"1.0","name":"testcase_fast_forward.yarn","resourceType":"GMIncludedFile",},
],
"MetaData": {
"IDEVersion": "2022.3.0.625",
diff --git a/datafiles/testcase_fast_forward.yarn b/datafiles/testcase_fast_forward.yarn
new file mode 100644
index 00000000..bbeea6b6
--- /dev/null
+++ b/datafiles/testcase_fast_forward.yarn
@@ -0,0 +1,14 @@
+title: Start
+---
+A
+B
+C
+D
+E
+F
+<>
+G
+H
+I
+J
+===
\ No newline at end of file
diff --git a/objects/oTestCaseFastForward/Create_0.gml b/objects/oTestCaseFastForward/Create_0.gml
new file mode 100644
index 00000000..d35279bb
--- /dev/null
+++ b/objects/oTestCaseFastForward/Create_0.gml
@@ -0,0 +1,3 @@
+ChatterboxLoadFromFile("testcase_fast_forward.yarn");
+box = ChatterboxCreate();
+ChatterboxJump(box, "Start");
\ No newline at end of file
diff --git a/objects/oTestCaseFastForward/Draw_0.gml b/objects/oTestCaseFastForward/Draw_0.gml
new file mode 100644
index 00000000..17903e12
--- /dev/null
+++ b/objects/oTestCaseFastForward/Draw_0.gml
@@ -0,0 +1,55 @@
+draw_set_font(fntDefault);
+
+//Iterate over all text and draw it
+var _x = 10;
+var _y = 10;
+
+if (ChatterboxIsStopped(box))
+{
+ //If we're stopped then show that
+ draw_text(_x, _y, "(Chatterbox stopped)");
+}
+else
+{
+ //All the spoken text
+ var _i = 0;
+ repeat(ChatterboxGetContentCount(box))
+ {
+ var _string = ChatterboxGetContent(box, _i);
+ draw_text(_x, _y, _string);
+ _y += string_height(_string);
+ ++_i;
+ }
+
+ //Bit of spacing...
+ _y += 30;
+
+ if (ChatterboxIsWaiting(box))
+ {
+ //If we're in a "waiting" state then prompt the user for basic input
+ draw_text(_x, _y, "(Press Space)");
+ }
+ else
+ {
+ //All the options
+ var _i = 0;
+ repeat(ChatterboxGetOptionCount(box))
+ {
+ var _string = ChatterboxGetOption(box, _i);
+
+ if (ChatterboxGetOptionConditionBool(box, _i))
+ {
+ draw_text(_x, _y, string(_i+1) + ") " + _string);
+ }
+ else
+ {
+ draw_set_colour(c_grey);
+ draw_text(_x, _y, string(_i+1) + ") " + _string);
+ draw_set_colour(c_white);
+ }
+
+ _y += string_height(_string);
+ ++_i;
+ }
+ }
+}
\ No newline at end of file
diff --git a/objects/oTestCaseFastForward/Step_0.gml b/objects/oTestCaseFastForward/Step_0.gml
new file mode 100644
index 00000000..77425235
--- /dev/null
+++ b/objects/oTestCaseFastForward/Step_0.gml
@@ -0,0 +1,24 @@
+if (ChatterboxIsStopped(box))
+{
+ //Do nothing!
+}
+else if (ChatterboxIsWaiting(box))
+{
+ if (keyboard_check_released(vk_space))
+ {
+ ChatterboxContinue(box);
+ }
+ else if (keyboard_check_released(ord("F")))
+ {
+ ChatterboxFastForward(box);
+ }
+}
+else
+{
+ var _index = undefined;
+ if (keyboard_check_released(ord("1"))) _index = 0;
+ if (keyboard_check_released(ord("2"))) _index = 1;
+ if (keyboard_check_released(ord("3"))) _index = 2;
+ if (keyboard_check_released(ord("4"))) _index = 3;
+ if (_index != undefined) ChatterboxSelect(box, _index);
+}
\ No newline at end of file
diff --git a/objects/oTestCaseFastForward/oTestCaseFastForward.yy b/objects/oTestCaseFastForward/oTestCaseFastForward.yy
new file mode 100644
index 00000000..438f7377
--- /dev/null
+++ b/objects/oTestCaseFastForward/oTestCaseFastForward.yy
@@ -0,0 +1,35 @@
+{
+ "spriteId": null,
+ "solid": false,
+ "visible": true,
+ "spriteMaskId": null,
+ "persistent": false,
+ "parentObjectId": null,
+ "physicsObject": false,
+ "physicsSensor": false,
+ "physicsShape": 1,
+ "physicsGroup": 1,
+ "physicsDensity": 0.5,
+ "physicsRestitution": 0.1,
+ "physicsLinearDamping": 0.1,
+ "physicsAngularDamping": 0.1,
+ "physicsFriction": 0.2,
+ "physicsStartAwake": true,
+ "physicsKinematic": false,
+ "physicsShapePoints": [],
+ "eventList": [
+ {"isDnD":false,"eventNum":0,"eventType":0,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
+ {"isDnD":false,"eventNum":0,"eventType":3,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
+ {"isDnD":false,"eventNum":0,"eventType":8,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
+ ],
+ "properties": [],
+ "overriddenProperties": [],
+ "parent": {
+ "name": "Test Cases",
+ "path": "folders/Test Cases.yy",
+ },
+ "resourceVersion": "1.0",
+ "name": "oTestCaseFastForward",
+ "tags": [],
+ "resourceType": "GMObject",
+}
\ No newline at end of file
diff --git a/options/windows/options_windows.yy b/options/windows/options_windows.yy
index 29b670ab..c61b9371 100644
--- a/options/windows/options_windows.yy
+++ b/options/windows/options_windows.yy
@@ -1,7 +1,7 @@
{
"option_windows_display_name": "Chatterbox",
"option_windows_executable_name": "${project_name}",
- "option_windows_version": "2.5.1.0",
+ "option_windows_version": "2.6.0.0",
"option_windows_company_info": "@jujuadams",
"option_windows_product_info": "Chatterbox",
"option_windows_copyright_info": "@jujuadams (c) 2022",
diff --git a/rooms/rmTest/rmTest.yy b/rooms/rmTest/rmTest.yy
index cf812f93..24c7c3ba 100644
--- a/rooms/rmTest/rmTest.yy
+++ b/rooms/rmTest/rmTest.yy
@@ -14,7 +14,7 @@
],
"layers": [
{"instances":[
- {"properties":[],"isDnd":false,"objectId":{"name":"oTestCaseSetterLocalScope","path":"objects/oTestCaseSetterLocalScope/oTestCaseSetterLocalScope.yy",},"inheritCode":false,"hasCreationCode":false,"colour":4294967295,"rotation":0.0,"scaleX":1.0,"scaleY":1.0,"imageIndex":0,"imageSpeed":1.0,"inheritedItemId":null,"frozen":false,"ignore":false,"inheritItemSettings":false,"x":32.0,"y":32.0,"resourceVersion":"1.0","name":"inst_59A57EF","tags":[],"resourceType":"GMRInstance",},
+ {"properties":[],"isDnd":false,"objectId":{"name":"oTestCaseFastForward","path":"objects/oTestCaseFastForward/oTestCaseFastForward.yy",},"inheritCode":false,"hasCreationCode":false,"colour":4294967295,"rotation":0.0,"scaleX":1.0,"scaleY":1.0,"imageIndex":0,"imageSpeed":1.0,"inheritedItemId":null,"frozen":false,"ignore":false,"inheritItemSettings":false,"x":32.0,"y":32.0,"resourceVersion":"1.0","name":"inst_369DDD11","tags":[],"resourceType":"GMRInstance",},
],"visible":true,"depth":0,"userdefinedDepth":false,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"effectEnabled":true,"effectType":null,"properties":[],"resourceVersion":"1.0","name":"Example","tags":[],"resourceType":"GMRInstanceLayer",},
{"spriteId":null,"colour":4281542935,"x":0,"y":0,"htiled":false,"vtiled":false,"hspeed":0.0,"vspeed":0.0,"stretch":false,"animationFPS":15.0,"animationSpeedType":0,"userdefinedAnimFPS":false,"visible":true,"depth":100,"userdefinedDepth":false,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"effectEnabled":true,"effectType":null,"properties":[],"resourceVersion":"1.0","name":"Background","tags":[],"resourceType":"GMRBackgroundLayer",},
],
@@ -22,7 +22,7 @@
"creationCodeFile": "",
"inheritCode": false,
"instanceCreationOrder": [
- {"name":"inst_59A57EF","path":"rooms/rmTest/rmTest.yy",},
+ {"name":"inst_369DDD11","path":"rooms/rmTest/rmTest.yy",},
],
"inheritCreationOrder": false,
"sequenceId": null,
diff --git a/scripts/ChatterboxAddFunction/ChatterboxAddFunction.gml b/scripts/ChatterboxAddFunction/ChatterboxAddFunction.gml
index e1f2a908..5b0e71df 100644
--- a/scripts/ChatterboxAddFunction/ChatterboxAddFunction.gml
+++ b/scripts/ChatterboxAddFunction/ChatterboxAddFunction.gml
@@ -59,6 +59,7 @@ function ChatterboxAddFunction(_name, _in_function)
case "jump":
case "stop":
case "wait":
+ case "forcewait":
case "visited":
__ChatterboxError("Function name \"", _name, "\" is reserved for internal Chatterbox use.\nPlease choose another action name.");
return false;
diff --git a/scripts/ChatterboxCreate/ChatterboxCreate.gml b/scripts/ChatterboxCreate/ChatterboxCreate.gml
index 55a47216..67835024 100644
--- a/scripts/ChatterboxCreate/ChatterboxCreate.gml
+++ b/scripts/ChatterboxCreate/ChatterboxCreate.gml
@@ -64,6 +64,7 @@ function __ChatterboxClass(_filename, _singleton, _local_scope) constructor
current_instruction = undefined;
stopped = true;
waiting = false;
+ forced_waiting = false;
loaded = true;
wait_instruction = undefined;
@@ -193,12 +194,14 @@ function __ChatterboxClass(_filename, _singleton, _local_scope) constructor
{
//If we *are* processing this chatterbox then set this particular global to
//We pick this global up at the bottom of the VM
+ global.__chatterboxVMWait = true;
global.__chatterboxVMForceWait = true;
}
else
{
//Otherwise set up a waiting state
- waiting = true;
+ waiting = true;
+ forced_waiting = true;
wait_instruction = current_instruction;
}
}
@@ -230,15 +233,15 @@ function __ChatterboxClass(_filename, _singleton, _local_scope) constructor
return undefined;
}
- if (ChatterboxGetOptionCount(_chatterbox) > 0)
+ if (GetOptionCount() > 0)
{
__ChatterboxTrace("Error! Player is being prompted to make a choice, cannot fast forward");
return undefined;
}
- while ((ChatterboxGetOptionCount(_chatterbox) <= 0) && ChatterboxIsWaiting(_chatterbox) && !ChatterboxIsStopped(_chatterbox))
+ while ((GetOptionCount() <= 0) && IsWaiting() && !IsStopped() && !forced_waiting)
{
- ChatterboxContinue(_chatterbox);
+ Continue();
}
}
@@ -355,6 +358,7 @@ function __ChatterboxClass(_filename, _singleton, _local_scope) constructor
current_instruction = undefined;
stopped = true;
waiting = false;
+ forced_waiting = false;
}
loaded = false;
diff --git a/scripts/__ChatterboxClassNode/__ChatterboxClassNode.gml b/scripts/__ChatterboxClassNode/__ChatterboxClassNode.gml
index 831d6a5c..b3441ef0 100644
--- a/scripts/__ChatterboxClassNode/__ChatterboxClassNode.gml
+++ b/scripts/__ChatterboxClassNode/__ChatterboxClassNode.gml
@@ -346,11 +346,12 @@ function __ChatterboxCompile(_in_substring_array, _root_instruction)
break;
case "wait":
+ case "forcewait":
case "stop":
_remainder = __ChatterboxCompilerRemoveWhitespace(_remainder, true);
if (_remainder != "")
{
- __ChatterboxError("Cannot use arguments with <> or <>\n\Action was \"<<", _string, ">>\"");
+ __ChatterboxError("Cannot use arguments with <>, <>, or <>\n\Action was \"<<", _string, ">>\"");
}
else
{
diff --git a/scripts/__ChatterboxSystem/__ChatterboxSystem.gml b/scripts/__ChatterboxSystem/__ChatterboxSystem.gml
index fc15bfe7..07956bfb 100644
--- a/scripts/__ChatterboxSystem/__ChatterboxSystem.gml
+++ b/scripts/__ChatterboxSystem/__ChatterboxSystem.gml
@@ -1,7 +1,7 @@
#region Internal Macro Definitions
-#macro __CHATTERBOX_VERSION "2.5.1"
-#macro __CHATTERBOX_DATE "2022-07-02"
+#macro __CHATTERBOX_VERSION "2.6.0"
+#macro __CHATTERBOX_DATE "2022-07-03"
#macro CHATTERBOX_CURRENT global.__chatterboxCurrent
@@ -83,6 +83,7 @@ global.__chatterboxIndentSize = 0;
global.__chatterboxFindReplaceOldString = ds_list_create();
global.__chatterboxFindReplaceNewString = ds_list_create();
global.__chatterboxVMInstanceStack = [];
+global.__chatterboxVMWait = false;
global.__chatterboxVMForceWait = false;
global.__chatterboxCurrent = undefined;
if (!variable_global_exists("__chatterbox_functions")) global.__chatterboxFunctions = ds_map_create();
diff --git a/scripts/__ChatterboxVM/__ChatterboxVM.gml b/scripts/__ChatterboxVM/__ChatterboxVM.gml
index 880317fd..b0123fd0 100644
--- a/scripts/__ChatterboxVM/__ChatterboxVM.gml
+++ b/scripts/__ChatterboxVM/__ChatterboxVM.gml
@@ -13,6 +13,7 @@ function __ChatterboxVM()
stopped = false;
waiting = false;
+ forced_waiting = false;
wait_instruction = undefined;
entered_option = false;
leaving_option = false;
@@ -112,6 +113,7 @@ function __ChatterboxVMInner(_instruction)
{
if (((_next.type != "option") || CHATTERBOX_SINGLETON_WAIT_BEFORE_OPTION)
&& (_next.type != "wait")
+ && (_next.type != "forcewait")
&& (_next.type != "stop"))
{
waiting = true;
@@ -123,10 +125,16 @@ function __ChatterboxVMInner(_instruction)
break;
case "wait":
- global.__chatterboxVMForceWait = true;
+ global.__chatterboxVMWait = true;
if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<>");
break;
+ case "forcewait":
+ global.__chatterboxVMWait = true;
+ global.__chatterboxVMForceWait = true;
+ if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<>");
+ break;
+
case "jump":
if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "[goto ", _instruction.destination, "]");
@@ -173,7 +181,8 @@ function __ChatterboxVMInner(_instruction)
case "stop":
if (CHATTERBOX_WAIT_BEFORE_STOP && (array_length(content) > 0) && (array_length(option) <= 0))
{
- waiting = true;
+ waiting = true;
+ forced_waiting = true;
wait_instruction = _instruction;
}
else
@@ -228,10 +237,19 @@ function __ChatterboxVMInner(_instruction)
break;
}
- if (is_string(_result) && (_result == "<>"))
+ if (is_string(_result))
{
- global.__chatterboxVMForceWait = true;
- if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<> returned by function");
+ if (_result == "<>")
+ {
+ global.__chatterboxVMWait = true;
+ if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<> returned by function");
+ }
+ else if (_result == "<>")
+ {
+ global.__chatterboxVMWait = true;
+ global.__chatterboxVMForceWait = true;
+ if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<> returned by function");
+ }
}
break;
@@ -284,14 +302,17 @@ function __ChatterboxVMInner(_instruction)
}
}
- if (global.__chatterboxVMForceWait)
+ if (global.__chatterboxVMWait)
{
- global.__chatterboxVMForceWait = false;
- __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "<> (forced)");
+ if (__CHATTERBOX_DEBUG_VM) __ChatterboxTrace(__ChatterboxGenerateIndent(_instruction.indent), "Something insisted the VM wait");
- waiting = true;
+ waiting = true;
+ forced_waiting = global.__chatterboxVMForceWait;
wait_instruction = _instruction.next;
_do_next = false;
+
+ global.__chatterboxVMWait = false;
+ global.__chatterboxVMForceWait = false;
}
if (_do_next)