Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for objects (dot notation) in card requirements #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ YouTube](https://www.youtube.com/playlist?list=PLy3M_6DKN9joOGhUD1chHumc9aS6EZZ_
* [Cards with Covers](doc/cards-with-covers.md):
[twee](examples/covers.tw),
[html](https://joshuagrams.github.io/tiny-qbn/examples/covers.html).
* [Cards using objects in requirements](doc/dot-notation.md):
[twee](examples/dot-notation.tw),
[html](https://joshuagrams.github.io/tiny-qbn/examples/dot-notation.html)
* [Cards with Covers and objects in requirements](doc/cards-with-covers-dot-notation.md):
[twee](examples/covers-dot-notation.tw),
[html](https://joshuagrams.github.io/tiny-qbn/examples/covers-dot-notation.html).
* [Inline Choices](doc/choices.md):
[twee](examples/choices.tw),
[html](https://joshuagrams.github.io/tiny-qbn/examples/choices.html).
Expand Down
19 changes: 19 additions & 0 deletions doc/cards-with-covers-dot-notation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Card Covers with objects using dot notation in requirements
===========

This example is identical to [cards with covers](cards-with-covers.md). The only difference is that it uses objects within the card requirements rather than simple variables. Instead of `$strength`, the characters stats are defined as an object in StoryInit: `<<set $pc = {'strength': 1, 'stealth': 1}>>`.

The individual properties of that object can be used in requirements using dot notation syntax. To access the `strength` property, you'd refer to it as `$pc.strength` (in requirements expressed using comment syntax) or `pc.strength` (in requirements expressed in tag syntax)

For example:

`::Card Title [card req-pc.strength-gte-2]`

or

``::Card Title\
/*QBN\
sticky-card\
req: $pc.strength gte 2\
also: $pc.strength gte 3\
*/``
18 changes: 18 additions & 0 deletions doc/dot-notation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Using objects in requirements
===========

It is possible to use object properties within card requirements. In this example, the player characters stats are defined an object in StoryInit using `<<set $pc = {'strength': 1, 'stealth': 1}>>`.

The individual properties of that object can be used in requirements using dot notation syntax. To access the `strength` property, you'd refer to it as `$pc.strength` (in requirements expressed using comment syntax) or `pc.strength` (in requirements expressed in tag syntax)

For example:

`::Card Title [card req-pc.strength-gte-2]`

or

``::Card Title\
/*QBN\
sticky-card\
req: $pc.strength gte 2\
*/``
2 changes: 1 addition & 1 deletion examples/choices.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/common/tiny-qbn.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/common/tiny-qbn.txt

Large diffs are not rendered by default.

302 changes: 302 additions & 0 deletions examples/covers-dot-notation.html

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions examples/covers-dot-notation.tw
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
::StoryTitle
Cards with Covers and Objects (dot notation)

::StoryData
{"ifid": "A62F5683-9EF5-4ECE-A911-7EEDCFD6B046"}

::StoryInit
<<set $pc = {'strength': 1, 'stealth': 1}>>

::Start
Strength: $pc.strength ([[increase strength->Start][$pc.strength to $pc.strength + 1]])

-----

You round a bend in the trail and come face to...chest with a four-legged monster that has horns like giant spaghetti servers. Or should that be antlers? Whatever they are, it shakes them angrily at you.

<<includeall `QBN.cards().sort(QBN.alphabetically)` "coverbox">>

::Back away slowly [sticky-card]
<<if _qbn_cover>><<linkcontents>><<else>>\
Moving slowly so as not to incite its hunting instincts, you tiptoe backwards until you can no longer see the beast.

<<return>>
<</if>>

::Play dead [sticky-card]
<<if _qbn_cover>>\
<<linkcontents "Play dead and hope it doesn't eat you">>\
<<else>>\
The better part of valor is discretion, in the which better part I have sav'd my life.
--Falstaff

You curl into a ball on the ground and lie motionless. The beast snuffles you, but after a terrifying eternity, it wanders away, leaving you miraculously un-gored and un-trampled.

<<return>>
<</if>>

::Very Strong
/*QBN
sticky-card
req: $pc.strength gte 2
also: $pc.strength gte 3
*/\
<<if _qbn_cover>>\
<<linkcontents "Use brute force">> (requires <<requirements>>)\
<<else>>\
You leap at the beast, screaming wildly, and grab its antlers. Or horns? Whatever. You wrench them to the side, driving it to its knees, and sit on its head. It attempts to get up, but doesn't have the leverage. When it seems properly cowed, you release it, and it saunters off into the brush, trying to pretend that it meant to do that all along.

<<return>>
<</if>>
2 changes: 1 addition & 1 deletion examples/covers.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/dice-rolls.html

Large diffs are not rendered by default.

288 changes: 288 additions & 0 deletions examples/dot-notation.html

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions examples/dot-notation.tw
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
:: StoryTitle
Objects (dot notation)


:: StoryData
{
"ifid": "2F0032CE-E4AF-4CDE-89BC-0BC33A71ECE7"
}

::StoryInit
<<set $character_points to 3>>
<<set $pc = {'strength': 1, 'stealth': 1}>>

::Start
Unused character points: $character_points
Strength: $pc.strength ([[Increase strength->Start][$pc.strength++; ; $character_points--]])
Stealth: $pc.stealth ([[Increase stealth->Start][$pc.stealth++; $character_points--]])

-----

You round a bend in the trail and come face to...chest with a four-legged monster that has horns like giant spaghetti servers. Or should that be antlers? Whatever they are, it shakes them angrily at you.

<<cardrow `QBN.cards().sort(QBN.alphabetically)` "linkbox">>\

::Back away slowly [sticky-card]
Moving slowly so as not to incite its hunting instincts, you tiptoe backwards until you can no longer see the beast.

<<return>>

::Play dead and hope it doesn't eat you [sticky-card]
The better part of valor is discretion, in the which better part I have sav'd my life.
--Falstaff

You curl into a ball on the ground and lie motionless. The beast snuffles you, but after a terrifying eternity, it wanders away, leaving you miraculously un-gored and un-trampled.

<<return>>

::Use brute force [sticky-card req-pc.strength-gte-2]

You leap at the beast, screaming wildly, and grab its antlers. Or horns? Whatever. You wrench them to the side, driving it to its knees, and sit on its head. It attempts to get up, but doesn't have the leverage. When it seems properly cowed, you release it, and it saunters off into the brush, trying to pretend that it meant to do that all along.

::Sneak past the beast [sticky-card req-pc.stealth-gte-2]

You back away from the beast until it is out of sight. Looking to your left, you see a barely noticeable gap in the scrub. You crouch down and inch your way through the bushes back towards the beast. It fails to notice as you creep past it. Once you round a further bend, you emerge from the bush and congratulate yourself on your stealthy escape.
2 changes: 1 addition & 1 deletion examples/localvore.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/priority.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/progress.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/sprawl.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/tutorial-1.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/tutorial-2.html

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
"ex-localvore2": "cd examples && tweego -o tutorial-2.html tutorial-2.tw common",
"ex-localvore": "cd examples && tweego -o localvore.html localvore.tw common",
"ex-covers": "cd examples && tweego -o covers.html covers.tw common",
"ex-covers-dot-notation": "cd examples && tweego -o covers-dot-notation.html covers-dot-notation.tw common",
"ex-choices": "cd examples && tweego -o choices.html choices.tw common",
"ex-dot-notation": "cd examples && tweego -o dot-notation.html dot-notation.tw common",
"ex-priority": "cd examples && tweego -o priority.html priority.tw common",
"ex-progress": "cd examples && tweego -o progress.html progress.tw common",
"ex-sprawl": "cd examples && tweego -o sprawl.html sprawl.tw sprawl.css common",
"ex-dice-rolls": "cd examples && tweego -o dice-rolls.html dice-rolls.tw common",
"examples": "npm run copy-common && npm run ex-localvore1 && npm run ex-localvore2 && npm run ex-localvore && npm run ex-covers && npm run ex-choices && npm run ex-priority && npm run ex-progress && npm run ex-sprawl && npm run ex-dice-rolls"
"examples": "npm run copy-common && npm run ex-localvore1 && npm run ex-localvore2 && npm run ex-localvore && npm run ex-covers && npm run ex-covers-dot-notation && npm run ex-choices && npm run ex-dot-notation && npm run ex-priority && npm run ex-progress && npm run ex-sprawl && npm run ex-dice-rolls"
},
"author": "Josh Grams <[email protected]>",
"license": "ISC",
Expand Down
24 changes: 20 additions & 4 deletions story-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ window.QBN = QBN

QBN.parseTagsInto = function(text, tags) {
let patterns = [
"[a-zA-Z0-9-_]+(?:\\s+|$)", // tag
"[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*", // tag with TwineScript expression
"[a-zA-Z0-9-_\\.]+(?:\\s+|$)", // tag
"[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*", // tag with TwineScript expression
"[^\\n]+(?:\\n|$)\\s*" // continue expression or error
]
let tokenPattern = new RegExp('(' + patterns.join(')|(') + ')', 'g')
Expand Down Expand Up @@ -426,9 +426,25 @@ Macro.add('range', {
}
})

QBN.getProperty = function(propertyName, object) {
var parts = propertyName.split("."),
length = parts.length,
i,
property = object || this;
for (i = 0; i < length; i++) {
if (parts[i] in property) {
property = property[parts[i]];
} else {
i = length
property = undefined
}
}
return property;
}

QBN.value = function(name) {
var v = State.variables, t = State.temporary
return t[name] != null ? t[name] : v[name]
var v = QBN.getProperty(name, State.variables), t = QBN.getProperty(name, State.temporary)
return t != null ? t : v
}

QBN.requirementMet = function(req) {
Expand Down
Loading