From f342b4f1fa4e2c9486953cf9114a554f1e5af00e Mon Sep 17 00:00:00 2001 From: Rudis Muiznieks Date: Thu, 3 Jul 2014 09:56:35 -0500 Subject: [PATCH 1/2] added ability to check for false condition states in hrefs --- src/example/testing.md | 63 ++++++++++++++++++++++++++++++++---------- src/parser.coffee | 2 +- src/player.coffee | 4 +-- src/util.coffee | 22 +++++++++++---- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/example/testing.md b/src/example/testing.md index ddf256e..fd3706f 100644 --- a/src/example/testing.md +++ b/src/example/testing.md @@ -1,28 +1,61 @@ -# [Testing](/scene) +# [Cloak of Darkness](/foyer) -Testing +A basic IF demonstration. -## Scene +Hurrying through the rainswept November night, you're glad to see the bright lights of the Opera House. It's surprising that there aren't more people about but, hey, what do you expect in a cheap demo game...? -> This is first-seen text for the main scene. +## [Foyer]("Foyer of the Opera House") -This is a test. +[You](#examined-self) are standing in a spacious hall, splendidly decorated in red and gold, with glittering chandeliers overhead. The entrance from the street is to the [north](#tried-to-leave), and there are doorways [south](/bar) and [west](/cloakroom). -- [|Set condition](?condition#condition) -- [Go to another scene](/another-scene) +### Tried to Leave -## Another Scene +[You've](#examined-self) only just arrived, and besides, the weather outside seems to be getting worse. -> This is the first seen text of the unconditional scene. +### Examined Self -This is the regular text of the unconditional scene. +[You aren't carrying anything.|You are wearing a handsome cloak, of velvet trimmed with satin, and slightly splattered with raindrops. Its blackness is so deep that it almost seems to suck light from the room.](?lost-cloak) -- [Go back](/scene) +## Cloakroom -## [Another Scene](?condition) +The walls of this small room were clearly once lined with hooks, though now only one remains. The exit is a door to the [east](/foyer). -> This is the first seen text of the conditional scene. +[Your cloak is on the floor here.](?dropped-cloak) +[Your cloak is hanging on the hook.](?hung-cloak) -This is the regular text of the conditional scene. +- [Examine the hook.](#examined-hook) +- [Hang your cloak on the hook.](?examined-self&!lost-cloak#lost-cloak+hung-cloak) +- [Drop your cloak on the floor.](?examined-self&!lost-cloak#lost-cloak+dropped-cloak) -- [Go back](/scene) +### Examined Hook + +It's just a small brass hook, [with your cloak hanging on it|screwed to the wall](?hung-cloak). + +## [Bar]("Foyer Bar") + +You walk to the bar, but it's so dark here you can't really make anything out. The foyer is back to the [north](/foyer). + +- [Feel around for a light switch.](?!scuffled1#scuffled1+not-in-the-dark) +- [Sit on a bar stool.](?!scuffled2#scuffled2+not-in-the-dark) + +### Not in the Dark + +In the dark? You could easily disturb something. + +## [Bar](?lost-cloak "Foyer Bar") + +The bar, much rougher than you'd have guessed after the opulence of the foyer to the north, is completely empty. There seems to be some sort of message scrawled in the sawdust on the floor. The foyer is back to the [north](/foyer). + +[Examine the message.](/message) + +## [Message]("Foyer Bar") + +The message, neatly marked in the sawdust, reads... + +**You have won!** + +## [Message](?scuffled1&scuffled2 "Foyer Bar") + +The message has been carelessly trampled, making it difficult to read. You can just distinguish the words... + +**You have lost.** diff --git a/src/parser.coffee b/src/parser.coffee index d8f8354..1e81b06 100644 --- a/src/parser.coffee +++ b/src/parser.coffee @@ -60,7 +60,7 @@ blockToScene = (block) -> key = normalize sceneName.text href = matchHref sceneName.href if href?.conditions? - conditions = href.conditions.split '&' + conditions = toBoolHash href.conditions.split '&' else title = trimText block.name key = normalize block.name diff --git a/src/player.coffee b/src/player.coffee index 9c6cc6c..deb9586 100644 --- a/src/player.coffee +++ b/src/player.coffee @@ -30,7 +30,7 @@ class Player for anchor in matchAnchors description href = matchHref anchor.href if href.conditions? - conditions = href.conditions.split '&' + conditions = toBoolHash href.conditions.split '&' satisfied = conditionsMet @playerState, conditions alts = splitAltText anchor.text replace = if satisfied then alts.passed else alts.failed @@ -87,7 +87,7 @@ class Player if @story.scenes[match.target]? for scene in @story.scenes[match.target] if conditionsMet @playerState, scene.conditions - if !matchedScene? or !scene.conditions? or !matchedScene.conditions? or scene.conditions.length > matchedScene.conditions.length + if !matchedScene? or !scene.conditions? or !matchedScene.conditions? or Object.keys(scene.conditions).length > Object.keys(matchedScene.conditions).length matchedScene = scene if matchedScene? @currentScene = matchedScene diff --git a/src/util.coffee b/src/util.coffee index 98049df..33e3370 100644 --- a/src/util.coffee +++ b/src/util.coffee @@ -2,7 +2,7 @@ regexLib = anchors: /(\[((?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[\])*\])*\])*\])*\])*\])*)\]\([ ]*((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\(\))*\))*\))*\))*\))*\))*)[ ]*((['"])(.*?)\5[ ]*)?\))/gm - href: /^(?:\/([a-zA-Z](?:-?[a-zA-Z0-9])*))?(?:\?((?:[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:&[a-zA-Z](?:-?[a-zA-Z0-9])*)*)?)?(?:#((?:[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:\+[a-zA-Z](?:-?[a-zA-Z0-9])*)*))?$/ + href: /^(?:\/([a-zA-Z](?:-?[a-zA-Z0-9])*))?(?:\?((?:!?[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:&!?[a-zA-Z](?:-?[a-zA-Z0-9])*)*)?)?(?:#((?:[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:\+[a-zA-Z](?:-?[a-zA-Z0-9])*)*))?$/ trim: /^\s+|\s+$/g @@ -52,13 +52,23 @@ matchHref = (href) -> normalize = (text) -> text.toLowerCase().replace(/^\W+|\W+$/g, '').replace /\W+/g, '-' +toBoolHash = (names) -> + if !names? + return null + hash = {} + for name in names + if name.indexOf('!') == 0 + hash[name.substring 1, name.length] = false + else + hash[name] = true + return hash + conditionsMet = (state, conditions) -> met = true - if conditions? - for condition in conditions - if !state[condition]? - met = false - break + for cond, val of conditions + if (val and !state[cond]) or (!val and state[cond]) + met = false + break return met splitAltText = (text) -> From df228633c894095b67b29531bc17e8448186358e Mon Sep 17 00:00:00 2001 From: Rudis Muiznieks Date: Thu, 3 Jul 2014 16:21:56 -0500 Subject: [PATCH 2/2] fixed restart link at end of game --- src/player.coffee | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/player.coffee b/src/player.coffee index deb9586..9704cf7 100644 --- a/src/player.coffee +++ b/src/player.coffee @@ -65,11 +65,13 @@ class Player checkGameOver: -> if @container.find('a:not(.disabled):not(.external)').length == 0 @container.append @converter.makeHtml '## The End\n\nYou have reached the end of this story. Click here to start over.' - $('#restart').click -> - @container.empty() - player = new Player @story, @id - $("##{@id}").data 'player', player + $('#restart').data('info', [@id, @story]).click -> + info = $(this).data 'info' + $("##{info[0]}").empty() + player = new Player info[1], info[0] + $("##{info[0]}").data 'player', player player.play() + return false handleHref: (href) -> match = matchHref href