Adapt StoryManager for Snowman

This commit is contained in:
2025-09-13 21:19:15 -07:00
parent 74c27cba67
commit e5b8f7db4f
3 changed files with 78 additions and 46 deletions

View File

@ -1,4 +1,6 @@
var State = window.story.state
State.variables = Object.create(null)
// Game stats
State.variables.reputation = 0;
State.variables.playerKnowledge = {poetry: 0, industry: 0, astronomy: 0};

View File

@ -6,7 +6,7 @@ At the Duchess's Party
"ifid": "BE18C022-A213-466C-8DD1-DCCD5CB1DF48"
}
:: Story JavaScript [script]
:: Story JavaScript
Config.passages.nobr = true; // Deal with linebreaks.
:: Start
@ -16,33 +16,39 @@ Of course it isn't. The hall is filled with aristocrats in evening-wear, making
:: Circulating
You mingle through the crowd, keeping a wary eye around you.<br>
<<getStoryletLinks 3 "circulating">>
<%= window.SM.getStoryletLinks(3, "circulating") %>
:: Conversation
<<set $talkingTo = $currentStorylet.character>>
You talk with $talkingTo.name. <br>
<<getStoryletLinks 3 "during conversation">>
<% s.variables.talkingTo = window.SM.currentStorylet.character %>
You talk with <%= window.SM.currentStorylet.character.name %>. <br>
<%= window.SM.getStoryletLinks(3, "during conversation") %>
[[Keep circulating|Circulating]]
:: Being approached
$currentStorylet.character.name is coming toward you to talk. <br>
You can [[talk to them | Conversation]], or risk snubbing them by [[trying to get away | Circulating][$reputation = $reputation - 1]].
<%= window.SM.currentStorylet.character.name %> is coming toward you to talk. <br>
You can [[talk to them|Conversation]], or risk snubbing them by <div onclick="s.variables.reputation -= 1">[[trying to get away|Circulating]]</div>.
:: Conversation topic
<<set $topic = $currentStorylet.topic>>
<<if $playerKnowledge[$topic] < $talkingTo[$topic] >>
$talkingTo.name tells you about <<print $conversationTopics[$topic][$playerKnowledge[$topic]]>>.
<<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>>
<<set $reputation = $reputation - 0.5>>
<<elseif $playerKnowledge[$topic] == $talkingTo[$topic]>>
You and $talkingTo.name discuss <<print $conversationTopics[$topic][$playerKnowledge[$topic]]>>.
<<set $reputation = $reputation + 1>>
<<elseif $playerKnowledge[$topic] > $talkingTo[$topic]>>
You tell $talkingTo.name about <<print $conversationTopics[$topic][$talkingTo[$topic]]>>.
<<set $characters[$talkingTo.id][$topic] = $talkingTo[$topic] + 1>>
They listen intently, and seem impressed.
<<set $reputation = $reputation + 2>>
<</if>><br><br>
<% var topic = window.SM.currentStorylet.character %>
<% var topic = window.SM.currentStorylet.topic
if (s.variables.playerKnowledge[topic] < s.variables.talkingTo[topic]) { %>
<%= s.variables.talkingTo.name %> tells you about <%= s.variables.conversationTopics[topic][s.variables.playerKnowledge[topic]] %>
<%
s.variables.playerKnowledge[topic] += 1
s.variables.reputation -= 0.5
} else if (s.variables.playerKnowledge[topic] == s.variables.talkingTo[topic]) { %>
You and <%= s.variables.talkingTo.name %> discuss <%= s.variables.conversationTopics[topic][s.variables.playerKnowledge[topic]] %>
<%
s.variables.reputation += 1
} else { %>
You tell <%= s.variables.talkingTo.name %> about <%= s.variables.conversationTopics[topic][s.variables.playerKnowledge[topic]] %>
They listen intently and seem impressed.
<%
s.variables.talkingTo[topic] += 1
s.variables.reputation += 2
}
%>
[[Keep circulating|Circulating]]

View File

@ -3,6 +3,8 @@
// -----------------------------------------------------------------------
var StoryManager = {};
StoryManager.storylets = {};
StoryManager.nextStoryletCache = [];
StoryManager.currentStorylet = Object.create(null);
StoryManager.getAllStorylets = function(tag=null) {
let allStorylets = [];
@ -99,32 +101,54 @@ StoryManager.weightedRandom = function(allStorylets, n) {
return selectedStorylets;
}
StoryManager.setCurrentStorylet = function(id) {
if (Object.hasOwn(StoryManager.nextStoryletCache, id)) {
StoryManager.currentStorylet = StoryManager.nextStoryletCache[id]
StoryManager.nextStoryletCache = Object.create(null);
} else {
console.log("Error: didn't find storylet cache entry: " + id);
}
}
StoryManager.getStoryletLinks = function(n, tag, selection) {
var links = _.map(StoryManager.getStorylets(n, tag, selection), function(storylet) {
// Maybe store the current storylet in a map generating a unique ID, then
// add some code below looking it up via that ID?
//
// How to keep storylets from building up over time?
// Clear them when a passage is left
var id = _.uniqueId("storylet-key_")
StoryManager.nextStoryletCache[id] = storylet;
return "<div onclick=\"window.SM.setCurrentStorylet('" + id + "');\" >[[" + storylet.description + "|" + storylet.passage + "]]<br></div>"
})
return _.reduce(links, function(memo, link) { return memo + link }, "")
}
// Set up macros
// ---------------------------------------------------------------
Macro.add("getStoryletLinks", {
handler: function() {
let n, tag, selection;
[n=null, tag=null, selection="ordered"] = this.args;
State.temporary.nextStorylets = StoryManager.getStorylets(n, tag, selection);
$(this.output).wiki(`\
<<for _storylet range _nextStorylets>> \
<<capture _storylet>> \
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
<</capture>> \
<</for>> \
`)
}
});
// Macro.add("getStoryletLinks", {
// handler: function() {
// let n, tag, selection;
// [n=null, tag=null, selection="ordered"] = this.args;
// State.temporary.nextStorylets = StoryManager.getStorylets(n, tag, selection);
// $(this.output).wiki(`\
// <<for _storylet range _nextStorylets>> \
// <<capture _storylet>> \
// [[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
// <</capture>> \
// <</for>> \
// `)
// }
// });
Macro.add("linkToNextStorylet", {
handler: function() {
let text, tag, selection;
[text, tag=null, selection="weighted"] = this.args;
State.temporary.nextStorylet = StoryManager.getStorylets(1, tag, selection)[0];
$(this.output).wiki(`<<capture _nextStorylet>>[[${text}|_nextStorylet.passage][$currentStorylet=_nextStorylet]]<</capture>>`);
}
});
// Macro.add("linkToNextStorylet", {
// handler: function() {
// let text, tag, selection;
// [text, tag=null, selection="weighted"] = this.args;
// State.temporary.nextStorylet = StoryManager.getStorylets(1, tag, selection)[0];
// $(this.output).wiki(`<<capture _nextStorylet>>[[${text}|_nextStorylet.passage][$currentStorylet=_nextStorylet]]<</capture>>`);
// }
// });
window.SM = StoryManager;