+2 votes
by (350 points)

So, I've seen SugarCube version of Leon's Combined Replace Macro Set. I'm interested in the <<once>> macro (and in turn, the <<becomes>> and <<later>> macros). In Leon's notes about this macro, he notes that:

If many <<once>> macros containing exactly identical text are used in different passages, seeing one of them will hide the others.

I'd like to be able to have identical <<once>> macros in multiple passages, but to have them triggered independently. For example, I have the exact same <<once>> macro describing identical rooms, A and B. I'd like to have the first <<once>> text to show when I visit both rooms for the first time. From the language of the note, it seems that after I visit A, when I visit B, I won't see the first <<once>> text.

How simple/complicated would it be to modify the macro to be passage independent?

2 Answers

+1 vote
by (63.1k points)
selected by
 
Best answer
Is there any particular reason why the visited() function won't work? I can't think of anything in particular that you could do with the modified version of the macro you describe that couldn't be done with visited(), but it's possible I'm missing something or not thinking of something.
by (350 points)
Good point. I suppose hasVisited(passage()) would work in an <<if>> for my purposes. I can probably then combine that with <<gains>> and things like that.

But I'm still going to hold out for a mod for the <<once>> macro. If it can/allowed to be modded, that is.
by (63.1k points)
edited by

I meant the actual visited() function that returns a number.  Anyway, here's a simple/easy to break example of how a macro that does something similar to <<once>> might work using the visited() function.

Macro.add('once', {
	   tags : ['becomes', 'remains'],
	handler : function () {

            var $wrapper    = $(document.createElement('span'));
            var length      = this.payload.length;
            var visit       = visited() - 1;
            var className   = 'macro-' + this.name;
            var lastTag     = this.payload[length-1].name;
            var lastContent = this.payload[length-1].contents;
            var content;

            if (visit >= length){
                content = (lastTag === 'remains') ? lastContent : '';
            } else {
                content = this.payload[visit].contents;
            }

            $wrapper
                .wiki(content)
                .addClass(className)
                .appendTo(this.output);
            }	
    });

Use it like this:

<<once>>\
  Content to show on first visit.
<<becomes>>\
  Content to show on next visit.
<<becomes>>\
  Content to show on third visit.
<<remains>>\
  Content to show on fourth visit and all subsequent visits.
<</once>>

I didn't look at Leon's original code, so it's very possible (likely) I'm missing some functionality that he had in his code, but this should work as a sexier replacement for 

<<if visited() is X>>Blah blah blah<</if>>

if that's all you're really after.  If you have the replace macros installed, you'll need to change the names of these macros if you want to try and use them as is.

by (350 points)
Now that's more like it. That looks like a working macro. I'll take it.
by (63.1k points)
I had a lot of unnecessary junk going on in that macro.  Didn't realize it until I reread it just now.  The other version was fine, but this version is a bit more sensible, so if you see this, I recommend using the edited one.
by (68.6k points)
edited by

Note: Posting a slightly more detailed version of this comment as its own answer.

The same thing may be accomplished via the <<switch>> macro:

<<switch visited()>>
<<case 1>>Content to show on first visit.
<<case 2>>Content to show on second visit.
<<case 3>>Content to show on third visit.
<<default>>Content to show on fourth and all subsequent visits.
<</switch>>

 

+3 votes
by (68.6k points)

Note: Even though I commented on Chapel's answer about using <<switch>> for this, I decided to repost it as its own answer since it offers somewhat more versatility than the others.

You may accomplish what you want using a combination of the <<switch>> macro and visited() function.  For example:

/* Cases serving one visit each; i.e. standard <<once>>-a-like. */
<<switch visited()>>
<<case 1>>Content to show on first visit.
<<case 2>>Content to show on second visit.
<<case 3>>Content to show on third visit.
<<default>>Content to show on fourth and all subsequent visits.
<</switch >>

/* Cases serving multiple visits. */
<<switch visited()>>
<<case 1>>\
	Content to show on first visit.
<<case 2 3>>\
	Content to show on second and third visits.
<<case 4 5 6 7>>\
	Content to show on fourth, fifth, sixth, and seventh visits.
<<default>>\
	Content to show on eighth and all subsequent visits.
<</switch >>

 

...