Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Return alert on save fail (sugarcube 2).

So I have saving deactivated in some parts of my game, like menus and combat. I initially was going to hide the save option, but that'll also prevent loading, so it's not quite the elegant solution I was hoping for (though it is plan b).

Instead, when the option to save is clicked within the save dialog, and the game does not in fact save, I'd like an alert to pop up and tell the player.

I'd appreciate some guidance on how exactly to do so without nuking the whole menu option.

Comments

  • edited February 2017
    May we assume you're using Config.saves.isAllowed? If not, exactly how are you disabling saves?
  • edited February 2017
    May we assume you're using Config.saves.isAllowed? If not, exactly how are you disabling saves?

    Whoops. Sorry about that. I'm using Config.saves.isAllowed, as in:
    Config.saves.isAllowed = function () {
    	if (tags().contains("combat")) {
    		return false;
    	} else if (tags().contains("menu")) {
    		return false;
    	} else {
    		return true;
    	}
    };
    

    I know I should probably be using an || there instead of an else if. In fact I'll probably just change that now.
  • edited February 2017
    You really should be using <Array>.includes() method, as the <Array>.contains…() family of methods are deprecated. In fact, since you're testing for multiple tags, I'd actually suggest the <Array>.includesAny() method instead. You also don't need the else clause here, simply make returning true the final statement in the function.

    As to alerting the player. You may use the UI.alert() dialog method, though that will take a bit of magic to make work from within the Config.saves.isAllowed callback.

    For example, try something like the following:
    config.saves.isAllowed = function () {
    	if (tags().includesAny("combat", "menu")) {
    		$(document).one('tw:dialogclosed', function () {
    			UI.alert("You can't save here, scrub!");
    		});
    
    		return false;
    	}
    
    	return true;
    };
    

    EDIT: The $(document).one('tw:dialogclosed', function () { … }) bit sets up an event handler which executes the UI.alert() dialog method when the Saves dialog closes. That is necessary because attempting to switch to the alert dialog from within the Config.saves.isAllowed callback without doing so will cause it to be closed whenever Config.saves.isAllowed returns. As I said, a bit of magic.
  • As always, worked perfectly.

    Thanks Exile.
  • @TheMadExile As long as we're talking about saves, I have a question and didn't think it deserved a whole new topic.

    In the SugarCube 2 Documentation, under Config Object, a note says:
    NOTE: SugarCube uses the story's title as the basis for the key used to store and load data used when playing the story and for saves. Because of this, the story title is not included in updates and it is strongly recommended that you do not add any kind of dynamic code to it.

    All well and good, makes sense.

    I have
    ::StoryTitle
    
    +Holy Land <<print $versionnumber>>
    

    And
    ::StoryMenu
    
    <<switch $chapter>>
    <<case 0>>
    	<<set document.title = "Holy Land: Prologue">>
    <<case 1>>
    	<<set document.title = "Holy Land: Chapter 1">>
    <<case 2>>
    	<<set document.title = "Holy Land: Chapter 2">>
    <<case 3>>
    	<<set document.title = "Holy Land: Chapter 3">>
    <<case 4>>
    	<<set document.title = "Holy Land: Chapter 4">>
    <<case 5>>
    	<<set document.title = "Holy Land: Chapter 5">>
    <<case 6>>
    	<<set document.title = "Holy Land: Chapter 6">>
    <<case 7>>
    	<<set document.title = "Holy Land: Chapter 7">>
    <<case 8>>
    	<<set document.title = "Holy Land: Epilogue">>
    <</switch>>
    

    II haven't run into any problems yet, but I was wondering if one or either of these was a potential problem. I don't want to be playing with fire.
  • First. I hope the blank line(s) you're putting between the passage name and code are only for illustrative purposes and you're not actually placing blank lines at the top of your passages for no good reason.

    Chapel wrote: »
    I have
    ::StoryTitle
    
    +Holy Land <<print $versionnumber>>
    
    You're printing a variable, which presumably can and will change, with the <<print>> macro. That is the very definition of dynamic code.

    I would suggest placing any version information in the StorySubtitle special passage and keeping StoryTitle static. For example:
    :: StoryTitle
    +Holy Land
    
    
    :: StorySubtitle
    – $versionnumber –
    
    NOTE: You don't really need the <<print>> macro to display a simple story/temporary variable due to the naked variable markup.


    If you simply must have it formatted as you do now. I'd again suggest keeping StoryTitle static, however, this time you'd hide its element. You'd then place the above code in either the StoryBanner or StorySubtitle special passage and style the associated element to look like the StoryTitle element normally does. For example:
    :: StoryTitle
    +Holy Land
    
    
    :: StorySubtitle
    +Holy Land $versionnumber
    
    
    :: Styles [stylesheet]
    #story-title {
    	display: none;
    }
    #story-subtitle {
    	font-size: 162.5%;
      	font-weight: bold;
    	margin: 0;
    }
    


    Chapel wrote: »
    And
    ::StoryMenu
    
    […]
    
    I recommend against putting that in the StoryMenu special passage. Its sole purpose is populate the story menu with links—it will not display anything other than links right now and I've toyed with the idea of making it skip processing of non-link markup altogether.

    The StoryCaption special passage is the usual go-to for code like that, though you'd want to ensure that no output was generated. That said, the PassageDone special passage would work just as well and is already silent.
  • Thanks.
    First. I hope the blank line(s) you're putting between the passage name and code are only for illustrative purposes and you're not actually placing blank lines at the top of your passages for no good reason.

    My mistake, that was in fact for illustrative purposes.
    That is the very definition of dynamic code.

    Haha. I'm bad at this. In my defense I read the warning after I'd already written the code, and since it hadn't lead to any problems, I thought maybe you meant something else.
    I recommend against putting that in the StoryMenu special passage. Its sole purpose is populate the story menu with links—it will not display anything other than links right now and I've toyed with the idea of making it skip processing of non-link markup altogether.

    I see. I have a display in that the StoryMenu too:
    <<display "audioMute">>
    
    It runs the passage:
    ::audioMute [nobr]
    <<link "Mute Sound">>
    	<<if $audioSwitch is 1>>
    		<<masteraudio mute>>
    		<<set $audioSwitch to 0>>
    	<<else>>
    		<<masteraudio unmute>>
    		<<set $audioSwitch to 1>>
    	<<endif>>
    <</link>>
    

    It works fine, but it seems like it might be best to change that soon, so thanks for the heads up.
  • You could/should simply put the <<link "Mute Sound">> directly into StoryMenu—including it obliquely via <<display>> seems like a bizarre choice.

    Also, unless you have something else in audioMute, the nobr tag wasn't doing anything useful—the <<link>> macro's contents are silent. It wasn't really hurting anything either, but my point is that less is more—i.e. don't do unnecessary stuff.
Sign In or Register to comment.