diff --git a/docs/README.md b/docs/README.md index cde7f1d..5157504 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,13 +1,15 @@ ## Chapel's Custom Macro Collection (v2.10.0) - [Try the demo!](https://macros.twinelab.net/demo) ([Sausage](https://github.com/ChapelR/custom-macros-demo)) -- [Downloads](./download ':ignore') +- [Downloads](https://macros.twinelab.net/download) - [Changelog](changelog.md) - [Release Notes](https://twinelab.net/blog/tags/macros/) +> [!NOTE] +> The Simple Inventory has been split off into [it's own library](https://inventory.twinelab.net)! + ### Documentation - **Gameplay Systems and Mechanics** - - [The Simple Inventory System](simple-inventory.md) - [The Cycles System](cycles-system.md) - [The Playtime System](playtime-system.md) - **Interface and Style** @@ -38,7 +40,7 @@ ### Installation Guide -To install these macros, all you need is the code. You can get the code by copy and pasting from the [repo](https://github.com/ChapelR/custom-macros-for-sugarcube-2/tree/master/scripts), or by generating a custom download using the [download utility](./download ':ignore'). If you use the downloader, select the scripts you want and click the `Create Download` button. Extract the files from the downloaded zip file and install the `bundle.js` and `bundle.css` files (see below). +To install these macros, all you need is the code. You can get the code by copy and pasting from the [repo](https://github.com/ChapelR/custom-macros-for-sugarcube-2/tree/master/scripts), or by generating a custom download using the [download utility](https://macros.twinelab.net/download). If you use the downloader, select the scripts you want and click the `Create Download` button. Extract the files from the downloaded zip file and install the `bundle.js` and `bundle.css` files (see below). If you opt to get the files from GitHub, It is highly recommended that you install the minified versions (found in the `scripts/minified/` [directory of the repo](https://github.com/ChapelR/custom-macros-for-sugarcube-2/tree/master/scripts/minified)), as these versions will have improved performance. You will only need the non-minified versions if you plan to edit the code in some way. Links to both the minified and pretty scripts are available on the individual documentation pages for each macro / system. diff --git a/docs/changelog.md b/docs/changelog.md index 6aead28..7042014 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,11 @@ [Back to the main page](./README.md). +### February 20, 2024 (v2.11.0) + +- **[Retired]** Removed Simple Inventory 2 in favor of [Simple Inventory 3](https://inventory.twinelab.net/). +- **[Docs]** Fixed several errors in the meter macro docs. + ### July 21, 2022 (v2.10.0) - **[Update]** A few small updates and fixes. diff --git a/docs/demo/index.html b/docs/demo/index.html index 92b58c9..fef5132 100644 --- a/docs/demo/index.html +++ b/docs/demo/index.html @@ -258,27 +258,22 @@ // v1.1.0, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 ;!function(){"use strict";if(Template&&Template.add&&"function"==typeof Template.add){var e={name:"gender",showSetting:!0,label:"Gender",desc:"",storyVar:"%%gender",default:"female"},t="#setting-control-"+e.name,r={subjective:["she","he","they"],objective:["her","him","them"],possessive:["hers","his","theirs"],determiner:["her","his","their"],reflexive:["herself","himself","themself"],noun:["woman","man","person"]};e.showSetting&&(Setting.addToggle(e.name,{label:e.label,desc:e.desc&&"string"==typeof e.desc&&e.desc.trim()?e.desc.trim():void 0}),$(document).on(":dialogopen :dialogopened",(function(){$("#ui-dialog-body").hasClass("settings")&&$(t).parent("div").empty().append($(document.createElement("button")).append("Configure...").ariaClick((function(){h()})))})));var a=/^is$/i,n=/^was$/i,s=/^has$/i,i=/oes$/i,o=/^[dl]ies$/i,l=/ies$/i,u=/sses$/i,c=/hes$/i,d=/s$/i,p=/they/i;Template.add(["he","she","they","He","She","They"],(function(){return S(this.name,g().subjective)})),Template.add(["him","her","them","Him","Her","Them"],(function(){return S(this.name,g().objective)})),Template.add(["his","hers","theirs","His","Hers","Theirs"],(function(){return S(this.name,g().possessive)})),Template.add(["his_","her_","their","His_","Her_","Their"],(function(){return S(this.name,g().determiner)})),Template.add(["himself","herself","themself","Himself","Herself","Themself"],(function(){return S(this.name,g().reflexive)})),Template.add(["man","woman","person","Man","Woman","Person"],(function(){return S(this.name,g().noun)})),Template.add(["he-s","she-s","they-re","He-s","She-s","They-re"],(function(){return S(this.name,g().subjective+T("'s","'re",y()))})),Macro.add("pronouns",{skipArgs:!0,handler:function(){h()}}),Macro.add("verb",{handler:function(){var e=y();if(this.args.length<1)return this.error("Please pass at least a singular third person pronoun to this macro.");this.args.includes("plural")&&(e=!0),this.output.append(T(String(this.args[0]),this.args[1]?String(this.args[1]):null,!!e))}}),setup.gender={pronouns:g,setPronouns:function(t){return"string"==typeof t?v(t):"object"==typeof t?function(t){if("object"==typeof t)return State.variables[e.storyVar]=v("male"===e.default?1:0),Object.assign(State.variables[e.storyVar],t)}(t):void 0},dialog:h,pluralize:b},window.gender=window.gender||setup.gender}else alert("Warning, this version of SugarCube does not include the Template API. Please upgrade to v2.29.0 or higher.");function m(){var t=$(document.createElement("div"));var a=Object.keys(r).map((function(t){var a=2;"male"===e.default?a=1:"female"===e.default&&(a=0);var n=State.variables,s=r[t][a];return n[e.storyVar]&&n[e.storyVar][t]&&(s=n[e.storyVar][t]),function(e,t,r){return $(document.createElement("label")).append(e).css("display","block").append($(document.createElement("input")).attr({type:"text",name:t}).css({float:"right","margin-left":"0.2em"}).val(r))}(t.toUpperFirst()+": ","gender-"+t,s)})),n=function(e,t,r){var a=$(document.createElement("select")).attr("name",t).css("float","right");return r.forEach((function(e,t){console.log(t),$(document.createElement("option")).attr("value",String(t)).append(e).appendTo(a)})),$(document.createElement("label")).css("display","block").append(e,a)}("Presets: ","gender-preset",["She/Her","He/Him","They/Them"]).on("change",(function(){var e=Number($(this).find("select").val());Number.isNaN(e)||a.forEach((function(t){var a=t.find("input"),n=a.attr("name").split("-")[1];a.val(r[n][e])}))})),s=n.find("select");State.variables[e.storyVar]?s.val(""):"male"===e.default?s.val("1"):"female"===e.default?s.val("0"):s.val("2");var i,o=$(document.createElement("button")).wiki("Confirm").addClass("gender-confirm").ariaClick({label:"Confirm pronoun selection."},(function(){var t=State.variables;t[e.storyVar]={},a.forEach((function(r){var a=r.find("input"),n=a.attr("name").split("-")[1];t[e.storyVar][n]=a.val().trim().toLowerCase()})),$("#ui-dialog-body").hasClass("reopen")&&UI.settings(),Dialog.close()})),l=(i=[n,"
"],a.forEach((function(e){i.push(e),i.push("
")})),i.push(o),i);return t.append(l)}function h(){var e,t,r,a;e="Customize Gender",t=m(),r="custom-gender",a=!1,Dialog.isOpen()&&$("#ui-dialog-body").hasClass("settings")&&(a=!0),Dialog.close(),Dialog.setup(e,a?r+" reopen":r),Dialog.append(t),Dialog.open()}function f(e){("number"!=typeof e||Number.isNaN(e)||e>2||e<0)&&(e=0);var t={};return Object.keys(r).forEach((function(a){t[a]=r[a][e]})),t}function g(){return State.variables[e.storyVar]&&State.variables[e.storyVar].subjective?State.variables[e.storyVar]:f("male"===e.default?1:0)}function v(t){var r;switch(t){case"female":r=f(0);break;case"male":r=f(1);break;default:r=f(2)}return State.variables[e.storyVar]=clone(r),r}function b(e){return e&&"string"==typeof e?(e=e.trim(),a.test(e)?e.replace(a,"are"):n.test(e)?e.replace(n,"were"):s.test(e)?e.replace(s,"have"):i.test(e)?e.replace(i,"o"):o.test(e)?e.replace(l,"ie"):l.test(e)?e.replace(l,"y"):u.test(e)?e.replace(u,"ss"):c.test(e)?e.replace(c,"h"):d.test(e)?e.replace(d,""):e):e}function y(){return p.test(g().subjective.trim())}function T(e,t,r){return r?t&&"string"==typeof t?t:b(e):e}function S(e,t){return e.first()===e.first().toUpperCase()?t.toUpperFirst():t}}(); // end pronouns.min.js -/* twine-user-script #22: "simple-inventory.min.js" */ -// simple-inventory.min.js, for SugarCube 2, by Chapel -// v2.3.0, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 -;!function(){"use strict";var r={tryGlobal:!0,defaultStrings:{empty:"The inventory is empty...",listDrop:"Discard",separator:"\n"}};function i(r,i,t,n){$(document).trigger({type:"initialized"===n?":inventory-init":":inventory-update",instance:r,receiving:i,moved:t,context:n})}function t(r){if(r=r?(r=[].slice.call(arguments)).flatten():[],!(this instanceof t))return new t(r);this.inv=r,i(this,null,r=r.length?r:null,"initialized")}Object.assign(t,{is:function(r){return r instanceof t},log:function(r){return t.is(r)?"Inventory.log() -> "+r.toArray().join(" - "):"Inventory.log() -> object is not an inventory..."},removeDuplicates:function(r){if(t.is(r)){var i,n=r.toArray();return i=[],n.forEach((function(r){i.includes(r)||i.push(r)})),i}}}),Object.assign(t.prototype,{transfer:function(r){if(arguments.length<2)return this;if(!t.is(r))return this;for(var n=[].slice.call(arguments),e=[],s=0,a=(n=n.slice(1).flatten()).length;s"),a.append(l)})),a):(a.wiki(r.defaultStrings.empty),a)},constructor:t,toJSON:function(){return JSON.reviveWrapper("new setup.Inventory("+JSON.stringify(this.inv)+")")},clone:function(){return new t(this.inv)}}),setup.Inventory=t,setup.simpleInv={inventory:t},r.tryGlobal&&(window.Inventory=window.Inventory||t),Macro.add("newinventory",{handler:function(){if(this.args.length<1)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');Wikifier.setValue(r,new t(this.args.slice(1).flatten()))}}),Macro.add("pickup",{handler:function(){if(this.args.length<2)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");i.pickUp(this.args.slice(1).flatten())}}),Macro.add("drop",{handler:function(){if(this.args.length<2)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");i.drop(this.args.slice(1).flatten())}}),Macro.add("transfer",{handler:function(){if(this.args.length<3)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");var n=this.args[1].trim();if("$"!==n[0]&&"_"!==n[0])return this.error('variable name "'+this.args[1]+'" is missing its sigil ($ or _)');var e=Wikifier.getValue(n);if(!t.is(e))return this.error("variable "+n+" is not an inventory!");i.transfer(e,this.args.slice(2).flatten())}}),Macro.add("dropall",{handler:function(){if(1!==this.args.length)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");i.empty()}}),Macro.add("clear","dropall",!1),Macro.add("sort",{handler:function(){if(1!==this.args.length)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");i.sort()}}),Macro.add("inventory",{handler:function(){if(this.args.length<1||this.args.length>2)return this.error("incorrect number of arguments");var r=this.args[0].trim();if("$"!==r[0]&&"_"!==r[0])return this.error('variable name "'+this.args[0]+'" is missing its sigil ($ or _)');var i=Wikifier.getValue(r);if(!t.is(i))return this.error("variable "+r+" is not an inventory!");var n=$(document.createElement("span")),e=!!this.args[1]&&this.args[1];n.wiki(i.show(e)).addClass("macro-"+this.name).appendTo(this.output)}}),Macro.add("linkedinventory",{handler:function(){if(this.args.length<2||this.args.length>3)return this.error("incorrect number of arguments");var r=!1,i="",n=this.args[1].trim(),e="string"==typeof this.args[0]&&this.args[0];if(!e)return this.error("first argument should be the link text");if("$"!==n[0]&&"_"!==n[0])return this.error('variable name "'+this.args[1]+'" is missing its sigil ($ or _)');var s=Util.slugify(n);s=this.name+"-"+s;var a=Wikifier.getValue(n);if(!t.is(a))return this.error("variable "+n+" is not an inventory!");if(this.args.length>2){if("$"!==(i=this.args[2].trim())[0]&&"_"!==i[0])return this.error('variable name "'+this.args[2]+'" is missing its sigil ($ or _)');if(r=Wikifier.getValue(i),!t.is(r))return this.error("variable "+i+" is not an inventory!")}a.linkedList(r,e).attr({id:s,"data-rec":i,"data-self":n,"data-action":e}).addClass("macro-"+this.name).appendTo(this.output)}})}(); -// end simple-inventory.min.js -/* twine-user-script #23: "speech.min.js" */ +/* twine-user-script #22: "speech.min.js" */ // speech.min.js, for SugarCube 2, by Chapel // v1.1.1, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 ;!function(){"use strict";var a=new Map;function t(t,e,r){if(void 0===r&&e&&(r=e,e=null),State.length)throw new Error("addCharacter() -> must be called before story starts");t&&r?(a.has(t)&&console.error('addCharacter() -> overwriting character "'+t+'"'),a.set(t,{displayName:e,image:r})):console.error("addCharacter() -> invalid arguments")}function e(t,e,r,s){var n=$(document.createElement("div")).addClass(Util.slugify(e)+" say"),i=a.has(e)?a.get(e).image:null,o=$(document.createElement("img")).attr("src",s||i||"");o.attr("src")&&o.attr("src").trim()&&n.append(o);var c=e.toUpperFirst();return a.has(e)&&a.get(e).displayName&&(c=a.get(e).displayName),n.append($(document.createElement("p")).wiki(c)).append($(document.createElement("p")).wiki(r)),t&&(t instanceof $||(t=$(t)),n.appendTo(t)),n}setup.say=e,setup.addCharacter=t,Macro.add("character",{handler:function(){t(this.args[0],this.args[1],this.args[2])}}),$(document).one(":passagestart",(function(){var t=Array.from(a.keys());t.push("say"),Macro.add(t,{tags:null,handler:function(){"say"!==this.name?e(this.output,this.name,this.payload[0].contents):e(this.output,this.args[0],this.payload[0].contents,this.args[1])}})}))}(); // end speech.min.js -/* twine-user-script #24: "swap-macro-set.min.js" */ +/* twine-user-script #23: "swap-macro-set.min.js" */ // swap-macro-set.min.js, for SugarCube 2, by Chapel // v1.1.0, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 ;!function(){"use strict";var t=!0,a=!0,e="violet",s="red",r="swappable";setup.swap=setup.swap||{};var n=null;function i(a){var e=function(){return a};setup.swap.current=e,t&&(window.swapCurrent=e)}function o(a,o){var p=$(document.createElement("span"));return $(document.createElement("a")).wiki(a).css("color",e).attr({"data-swap-flag":"false","data-orig-content":a,"data-wiki-code":o||""}).addClass(r).appendTo(p).ariaClick((function(a){a.preventDefault();var r=$(this);if("true"===r.attr("data-swap-flag"))r.attr("data-swap-flag","false").css("color",e),n=null;else if(n){var o=n.text(),p=r.text(),l=n.attr("data-wiki-code"),c=r.attr("data-wiki-code");n.attr("data-swap-flag","false").css("color",e).empty().wiki(p),r.attr("data-swap-flag","false").css("color",e).empty().wiki(o),l&&"string"==typeof l&&l.trim()&&(i(p),$.wiki(l)),c&&"string"==typeof c&&c.trim()&&(i(o),$.wiki(c)),setup.swap.current&&"function"==typeof setup.swap.current&&delete setup.swap.current,t&&window.swapCurrent&&"function"==typeof window.swapCurrent&&delete window.swapCurrent,n=null}else n=r,r.attr("data-swap-flag","true").css("color",s)})),p}function p(){n=null,$("a."+r).each((function(){var t=$(this);t.empty().wiki(t.attr("data-orig-content")).attr("data-swap-flag","false").css("color",e)}))}Macro.add("swap",{tags:["onswap"],skipArgs:!0,handler:function(){var t=this.payload[0].contents,a=this.payload[1]?this.payload[1].contents:"",e=this.output,s=this.name;o(t,a).addClass("macro-"+s).appendTo(e)}}),Macro.add("resetswap",{handler:function(){var t=this.args&&this.args[0]&&"string"==typeof this.args[0]?this.args[0]:"Reset";$(document.createElement(a?"button":"a")).wiki(t).ariaClick({label:"Reset all swappable elements."},(function(t){t.preventDefault(),p()})).appendTo(this.output)}}),setup.swap.create=o,setup.swap.reset=p}(); // end swap-macro-set.min.js -/* twine-user-script #25: "type-sim.min.js" */ +/* twine-user-script #24: "type-sim.min.js" */ // type-sim.min.js, for SugarCube 2, by Chapel // v2.0.0, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 ;!function(){"use strict";Macro.add("typesim",{tags:null,handler:function(){if(!this.args.length||!this.args[0]||"string"!=typeof this.args[0])return this.error("no text to type out was provided");var t,e=$(document.createElement("span")).addClass("macro"+this.name),n=$(document.createElement("div"));this.payload[0].contents&&this.payload[0].contents.trim()&&(t=this.payload[0].contents),function(t,e,n){if(t&&"string"==typeof t){!e||e instanceof $||(e=$(e));var i=0,s=t.split(""),a=[],o=$(document.createElement("textarea")).addClass("type-sim").on("input.type-sim",(function(){var e=$(this);i=a.push(s[i]),e.val(a.join("")),t.length===a.length&&(e.off("input.type-sim").ariaDisabled(!0),n&&"function"==typeof n&&n(a.join("")),$(document).trigger({type:":type-sim-end",message:a.join("")}))}));e&&e[0]&&e.append(o)}}(this.args[0],e,(function(){n.wiki(t)})),e.append(n).appendTo($(this.output))}})}(); // end type-sim.min.js -/* twine-user-script #26: "ui-macro.min.js" */ +/* twine-user-script #25: "ui-macro.min.js" */ // ui-macro.min.js, for SugarCube 2, by Chapel // v1.0.0, 2022-07-21, 3bdbdfbe5ae47a46e4f4e52766d78701939ae9a6 ;!function(){var s={update:UIBar.setStoryElements,stow:UIBar.stow,unstow:UIBar.unstow,toggle:function(){$("#ui-bar").hasClass("stowed")?UIBar.unstow():UIBar.stow()},hide:function(){$("#ui-bar").css("display","none")},show:function(){$("#ui-bar").css("display","block")},kill:function(){$("#ui-bar").css("display","none"),$("#story").css("margin-left","2.5em")},restore:function(){$("#ui-bar").css("display","block"),$("#story").css("margin-left","20em")},jump:UI.jumpto,saves:UI.saves,restart:UI.restart,settings:UI.settings,share:UI.share,aliases:{refresh:"update",reload:"update",destroy:"kill",revive:"restore",jumpto:"jump",save:"saves",load:"saves",setting:"settings",sharing:"share"}},r=Object.keys(s);function t(t){return t&&"string"==typeof t?function(s){return r.includes(s)}(t=t.toLowerCase().trim())||(t=function(r){return s.aliases[r]||null}(t))?(s[t](),!1):'Command "'+t+'" is not a valid command.':"Command is not a string."}Macro.add("ui",{handler:function(){Array.isArray(this.args)&&this.args.length||this.error("No commands passed to macro.");var s,r=function(s){if(!Array.isArray(s))return"Command list error.";var r=[];return s.forEach((function(s){r.push(t(s))})),r}(this.args.flatten());s=(r=r.filter((function(s){return"string"==typeof s}))).join(" "),r.length&&s&&this.error(s)}})}(); @@ -340,7 +335,6 @@ [[The Speech Box System|speech]] [[The Playtime System|playtime]] [[The Cycles System|cycles]] -[[The Simple Inventory|inventory]] [[The Typing Simulation Macro|typesim]] [[The Pronoun Templates|pronouns]] [[The Articles (A/An) Macros|articles]]/* embed gist */ @@ -691,83 +685,14 @@ [[Renavigate to this passage|passage()]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/first-macro]]The ''Simple Inventory'' is a group of macros, functions and methods, and events that can be used to manage simple, key-based inventory systems. What is a key-based inventory system? A system where the items you collect represent key items--items where the game checks that you have them, but the items don't need to have attributes of their own. In other words, this system is not ideal for things like equipment and potions, though it could be extended to handle such things. - -<<newinventory '$player'>><<newinventory '$container' 'hammer' 'knife'>>\ -You can create inventories with the {{{<<newinventory>>}}} macro. You'll need to save the inventory //instance// to a variable by providing the macro a variable name, which should be passed in quotes. Typically you want to initialize your inventories in you {{{StoryInit}}} [[special passage|http://www.motoslave.net/sugarcube/2/docs/#special-passage-storyinit]]. You can define as many inventories as you need, and transfer items between them. We'll create two inventories in this passage, one will be initialized with some items inside, another with any items. - -[[Continue|inventory2]] - ------ -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/simple-inventory]]On this passage, we'll give the user the opportunity to pick up a new item with the {{{<<pickup>>}}} macro. - -<<nobr>> - <<if not $player.has('chisel')>> - <<linkreplace 'Pick up the chisel.'>> - You got the chisel. - <<pickup '$player' 'chisel'>> - <</linkreplace>> - <<else>> - You got the chisel. - <</if>> -<</nobr>> - -[[Continue|inventory3]] - ------ -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/simple-inventory]]In this passage, we'll give the user the opportunity to pick up or drop some items into a chest. - -There's a treasure chest in this room! - -<<link 'Put some items in the chest.'>> - <<dialog 'Place items.'>> - <<linkedinventory 'leave' '$player' '$container'>> - <</dialog>> -<</link>> - -<<link 'Take some items from the chest.'>> - <<dialog 'Take items.'>> - <<linkedinventory 'take' '$container' '$player'>> - <</dialog>> -<</link>> - -[[Go back|inventory2]] - -[[Continue|inventory4]] - ------ -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/simple-inventory]]You can use the methods of the inventory instance to check whether an inventory has certain items, how many items it has, or whether it's empty, among many other things. - -<<if $player.has('knife')>>\ - You have a knife! -<</if>>\ -<<if $player.hasAll('hammer', 'chisel')>>\ - You have enough tools to chisel out some stone! -<</if>>\ -<<if $player.isEmpty()>>\ - Your inventory is empty! -<<else>>\ - You are carrying <<= $player.count()>> items in your inventory. -<</if>>\ - -[[Go back|inventory3]] - -[[Continue|inventory5]] - ------ -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/simple-inventory]]The Simple Inventory has a lot of features, so this is just a quick overview, for a deeper dive, check out the documentation. - -[[Go back|inventory4]] - ------ -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/simple-inventory]]The {{{<<message>>}}} macro can be used to create user-toggleable messages, such as for help, tutorials, or more information. We've been using it in the <<button 'View Source Code'>><</button>> buttons all across this file. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/first-macro]]The {{{<<message>>}}} macro can be used to create user-toggleable messages, such as for help, tutorials, or more information. We've been using it in the <<button 'View Source Code'>><</button>> buttons all across this file. <<message 'Help'>>\ It's a lot like the {{{<<linkappend>>}}} macro, but users can also remove the content when they're done.\ <</message>> ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/message-macro]]The meter macro set can be used to define cutomizable meters (like health bars, timers, progress bars, etc) and display and update them on the page. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/message-macro]]The meter macro set can be used to define cutomizable meters (like health bars, timers, progress bars, etc) and display and update them on the page. These meters are defined through the {{{<<newmeter>>}}} macro and its child tags, {{{<<colors>>}}}, {{{<<sizing>>}}}, {{{<<animation>>}}}, and {{{<<label>>}}}. You can also just define a meter with no child tags, in which case it will use the default meter settings. @@ -789,7 +714,7 @@ [[Continue|meters2]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]You can use the meters in a passage with the {{{<<showmeter>>}}} macro, and update their values (while animating them) with the {{{<<updatemeter>>}}} macro. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]You can use the meters in a passage with the {{{<<showmeter>>}}} macro, and update their values (while animating them) with the {{{<<updatemeter>>}}} macro. <<set _stamina to 75, _maxStamina to 75>>\ Health: <<showmeter 'health' `_health / _maxHealth`>> @@ -816,7 +741,7 @@ [[Go back|meters]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]You can also use meters to as timers, and plug into meter animations with the JavaScript API. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]You can also use meters to as timers, and plug into meter animations with the JavaScript API. <<set _time to 0>>\ Time until the bomb explodes: <<showmeter 'timer' 1>> @@ -829,7 +754,7 @@ [[Start over|meters]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]The {{{<<mouseover>>}}} macro can be used to trigger macro code on a variety of mouse and hover events. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/meter-macros]]The {{{<<mouseover>>}}} macro can be used to trigger macro code on a variety of mouse and hover events. Example of a "tooltip": @@ -849,9 +774,9 @@ <<mouseover>>[[Watch out for the pit!|pitfall]]<<onhover>><<goto 'pitfall'>><</mouseover>> ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/mouseover-macro]]You fell in a pit! Be more careful next time. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/mouseover-macro]]You fell in a pit! Be more careful next time. -[[Climb back out|mouseover]]<<notify>>Hi there!<</notify>>\ +[[Climb back out|mouseover]]<<notify>>Hi there!<</notify>>\ The {{{<<notify>>}}} macro can be used to display a quick message to users. It's less discruptive that a dialog or alert, and ideal for something like a quick inventory or achievement update. You can click the link below to fire another notification in case you missed the first one. Note, however, that allowing users to activate these notifications like this is a bad idea; if they click too much, the animations will start to trip over each other. <<link 'See a notification.'>> @@ -859,7 +784,7 @@ <</link>> ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/notify-macro]]This system can be used to display and record the user's playtime, much like in a lot of video games. The playtime system includes a function, a macro, and a passage tag. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/notify-macro]]This system can be used to display and record the user's playtime, much like in a lot of video games. The playtime system includes a function, a macro, and a passage tag. Your current playtime is: @@#time;<<playtime format>>@@ @@ -878,7 +803,7 @@ There's also a passage tag, {{{pausetimer}}}, which can be used to pause the play timer, for example when the user is in menus. ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/playtime-system]]The {{{<<popover>>}}} macro can be used to generate special dialog API modals that are designed to display full screen content. For example, consider try the following. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/playtime-system]]The {{{<<popover>>}}} macro can be used to generate special dialog API modals that are designed to display full screen content. For example, consider try the following. <<link "Click me!">> <<popover 'noclick'>>[img[assets/lisa.jpg]]<</popover>> @@ -898,7 +823,7 @@ <</link>> ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/popover]]The {{{<<preload>>}}} macro can be used to preload images. Preloading will improve performance as players click through the game, but will also increase startup time. It is recommended that users only load important images, like icons, and that users avoid loading tons of large images, like high-quality backgrounds. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/popover]]The {{{<<preload>>}}} macro can be used to preload images. Preloading will improve performance as players click through the game, but will also increase startup time. It is recommended that users only load important images, like icons, and that users avoid loading tons of large images, like high-quality backgrounds. The {{{<<preload>>}}} macro must be generally used in {{{StoryInit}}}. For example, this demo includes this line in {{{StoryInit}}}: @@ -913,7 +838,7 @@ </nowiki></code></pre>\ ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/preload]]The ''pronoun templates'' system is a drop-in system for handling player characters with configurable genders. It allows users to define and customize their preferred pronouns via a dialog modal that can be accessed via a macro or the {{{Setting}}} API. You can then leverage SugarCube's new {{{Template}}} API (add docs link) to use the templates in your game. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/preload]]The ''pronoun templates'' system is a drop-in system for handling player characters with configurable genders. It allows users to define and customize their preferred pronouns via a dialog modal that can be accessed via a macro or the {{{Setting}}} API. You can then leverage SugarCube's new {{{Template}}} API (add docs link) to use the templates in your game. <<link 'Configure your pronouns.'>> <<pronouns>> @@ -922,7 +847,7 @@ [[Next|pronouns2]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]<div class='poem'>\ +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]<div class='poem'>\ Nobody heard ?him, the dead ?man, But still ?he <<verb 'lies'>> moaning: I was much further out than you thought @@ -945,7 +870,7 @@ [[Handling verbs.|pronouns3]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]Pronouns also include a {{{<<verb>>}}} macro for pluralizing the verb forms or third person verbs. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]Pronouns also include a {{{<<verb>>}}} macro for pluralizing the verb forms or third person verbs. ?He <<verb 'waits'>>. @@ -959,7 +884,7 @@ [[Start over.|pronouns]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]The speech box system set is a set of macros and functions for creating speech boxes, like +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/pronoun-templates]]The speech box system set is a set of macros and functions for creating speech boxes, like You can use the {{{<<character>>}}} macro in your {{{StoryInit}}} special passage to create other custom macros that you can then use to display speech boxes. For example, the following line of code is in this demo file's {{{StoryInit}}} special passage: @@ -974,7 +899,7 @@ <<say 'bob' 'assets/bob.jpg'>>I am basically a meme now.<</say>> ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/speech-box-system]]The {{{<<swap>>}}} macro can be used to create puzzles or other creative forms of user interaction that invloves swapping words around on the page. The {{{<<onswap>>}}} macro can be used to make adjustments and run code when swaps occur, and inside the {{{<<onswap>>}}} block, the {{{swapCurrent()}}} function returns the text that is currently swapped in. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/speech-box-system]]The {{{<<swap>>}}} macro can be used to create puzzles or other creative forms of user interaction that invloves swapping words around on the page. The {{{<<onswap>>}}} macro can be used to make adjustments and run code when swaps occur, and inside the {{{<<onswap>>}}} block, the {{{swapCurrent()}}} function returns the text that is currently swapped in. <<set _catsPred to 'They meow constantly.'>>\ I <<swap>>own<<onswap>> @@ -989,7 +914,7 @@ [[Try another example.|swap2]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/swap-macro-set]]Here's an example of a simple number code puzzle implemented with the swap macro: +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/swap-macro-set]]Here's an example of a simple number code puzzle implemented with the swap macro: <<set _correct to [false, false, false]>>\ Enter the code: @@ -1033,14 +958,14 @@ [[Previous|swap]] ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/swap-macro-set]]The {{{<<typesim>>}}} macro allows you to //simulate// user input, but actually show them a predefined message. Try typing in the box below for an example: +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/swap-macro-set]]The {{{<<typesim>>}}} macro allows you to //simulate// user input, but actually show them a predefined message. Try typing in the box below for an example: <<typesim "You get to feel like you're typing, and that can be a cool interaction, but in reality, we just show you what we want you to see and make you say what we want you to say.">>\ Once the user finishes the message, you can run any code you like!\ <</typesim>>\ ----- -[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/type-sim]]The {{{<<ui>>}}} macro can be used to control many features of SugarCube's default UI from within macro code. +[[Documentation|https://twinelab.net/custom-macros-for-sugarcube-2/#/type-sim]]The {{{<<ui>>}}} macro can be used to control many features of SugarCube's default UI from within macro code. <<link 'Toggle the UI Bar'>> <<ui 'toggle'>> diff --git a/docs/download/fetch.js b/docs/download/fetch.js index 71458e6..ad83278 100644 --- a/docs/download/fetch.js +++ b/docs/download/fetch.js @@ -24,7 +24,6 @@ 'Dice Roller and Fairmath Functions' : 'operations', 'Playtime System' : 'playtime', 'Pronoun Templates' : 'pronouns', - 'Simple Inventory' : 'simple-inventory', 'The Speech Box System' : 'speech+css', 'Swap Macro Set' : 'swap-macro-set', 'The Typesim Macro' : 'type-sim', diff --git a/docs/guides/meter-macros-guide.md b/docs/guides/meter-macros-guide.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/guides/simple-inventory-guide.md b/docs/guides/simple-inventory-guide.md deleted file mode 100644 index cad2886..0000000 --- a/docs/guides/simple-inventory-guide.md +++ /dev/null @@ -1,248 +0,0 @@ -## The Simple Inventory (v2.x) Guide - -[Back to the main readme](../readme.md). - -This is a guide for the simple inventory system (v2.0.0 and later). This guide is intended to get you started with the system fast, by presenting some common use-cases and exploring certain features in plain English. However, you should still familiarize yourself with the documentation, as not all functionality or use-cases will be covered here. - -**THE CODE:** [Minified](https://github.com/ChapelR/custom-macros-for-sugarcube-2/blob/master/scripts/minified/simple-inventory.min.js). [Pretty](https://github.com/ChapelR/custom-macros-for-sugarcube-2/blob/master/scripts/simple-inventory.js). -**DEMO:** [Available](https://macros.twinelab.net/demo?macro=inventory). -**DOCUMENTATION:** [Available](../simple-inventory.md). - -## Contents - - * [Overview](#overview) - * [Macros](#macros) - * [Functions and methods](#functions-and-methods) - * [Events](#events) - * [Setting up an inventory](#setting-up-an-inventory) - * [Manipulating an inventory](#manipulating-an-inventory) - * [Testing an inventory for items](#testing-an-inventory-for-items) - * [Displaying an inventory](#displaying-an-inventory) - * [Multiple inventories](#multiple-inventories) - -## Overview - -The following is a brief list of all the macros, functions, methods, and other components included in the simple inventory system. For a more detailed look, check out the complete documentation. - -### Macros - - * `<>`: Creates a new inventory and stores a reference to it in the provided $variable, which must be quoted. You can optionally provide a list of items to add to the inventory. Your `StoryInit` special passage is the best place for these macros. You must create an inventory and assign it to a variable to use it with the other macros and methods. - * `<>`: Use this macro to add items to the indicated inventory. That inventory must have been previously setup using `<>` or similar. You must provide at least one item, and can provide as many as you want. If you start the list of items with the keyword `unique`, only items that are not currently in the inventory will be added to the inventory. - * `<>`: Removes items from a previously declared inventory. If an item in the **itemList** cannot be found in the inventory, it will be ignored. - * `<>` and `<>`: Removes all the items from the indicated inventory, emptying it. - * `<>`: Removes the indicated items from the first inventory and adds them to the second. If an item can't be found in the first inventory, it will be ignored and **not** added to the second inventory. - * `<>`: Sorts the indicated inventory alphanumerically. The default ordering (chronological) cannot easily be restored. - * `<>`: Displays the inventory in list form, separated by the indicated string or by the default string if no arguments are provided. - * `<>`: Creates a list similar to `<>`, but all items are separated by a newline and paired with a link. You can name the link with the **actionName** argument. If one inventory variable is provided to the macro, clicking the link drops the associated item. If to inventories are provided to the macro, clicking the link transfers the associated item to the second inventory. - -### Functions and Methods - - * `new Inventory([itemList])`: Creates a new inventory like `<>`. Can be stored to a variable: `<>`. - * `Inventory.is(variableName)`: Returns true if the passed variable is an inventory instance, false otherwise. - * `Inventory.log(variableName)`: Logs the contents of the inventory in question to the console for debugging. Also returns a string containing the same information that can be printed. - * `Inventory.removeDuplicates(variableName)`: Returns an array that contains the items in the indicated inventory, but with all repeated items removed. Can be used to enforce uniqueness. - * `.pickUp([unique], itemList)`: Similar to `<>`. Chainable. - * `.drop(itemList)`: Similar to `<>`. Chainable. - * `.empty()`: Similar to `<>` and `<>`. Chainable. - * `.transfer(variableName, itemList)`: Similar to `<>`. Chainable. - * `.has(itemList)`: Returns true if **any** of the provided items were found in the inventory. - * `.hasAll(itemList)`: Returns true if **all** of the provided items were found in the inventory. - * `.toArray()`: Returns a reference to the inventory's contents, as an array. Alterations to this array will be reflected in the inventory. - * `.sort()`: Similar to `<>`. Chainable. - * `.show([separator])`: Returns a string list of the inventory's contents, similar to `<>`. - -### Events - -One of two events is triggered in relation to the inventories: - - * `:inventory-init`: This event is fired whenever a new inventory is created. - * `:inventory-update`: This event is fired whenever an inventory is updated, but only after it has been created. - -Both of these events are sent to the handler with the following information you can use: - - * `.instance`: A reference to the calling instance. In transfers, that's the giving inventory. - * `.receiving`: A reference to the receiving instance, if it exists (i.e. in `<>` and `<>` calls), or `null`. - * `.moved`: An array of items that have been moved into or out of the calling inventory, or null if nothing was moved (for example, if items the player doesn't have were dropped, or a `<>` was used). - * `.context`: The context of the event: it's always one of the following strings: - * `'pickup'`: Some type of pickup action ocurred. Does not fire on items added with `<>` or similar. - * `'drop'`: Some type of drop action occured. Emptying or clearing the inventory also cause this context. - * `'transfer'`: A transfer between two inventories occured. - * `'initialized'`: A new inventory was created. If items were also added, they'll be in the `.moved` property. - * `'sort'`: The inventory was sorted. - -## Setting up an inventory - -Before you do anything else, you need to setup the inventory or inventories you want to use. For starters, we'll create a player inventory and call it `$inventory`. This inventory should start with no items; in other words, the player doesn't have anything at the start of the game. While we can do this in JavaScript using the `Inventory()` constuctor function, we'll focus on the macros in this guide. - -``` -<> -``` - -The above code sets the story variable `$inventory` to a new *instance* of an `Inventory`. This is similar to how we setup arrays and objects for use; in order to start treating the variable like an inventory we have to initialize it to be an inventory. - -Although we're using a different macro call, you should think of this as initializing a variable, and the best place to do that is in your `StoryInit` special passage. - -Once an inventory is initialized, we can use it with the other macros and methods. - -**Warning**. Failing to initalize an inventory and then using a simple inventory macro or method on it will cause an error. You should always, always initialize your variables, but this is especially critical for an inventory. - -## Manipulating an inventory. - -Now that we've created an inventory for the player, we can start to manipulate it. The most common actions you'll want to take with the inventory is to add and remove items from it. To add items, you'll use the `<>` macro: - -``` -<> -<> -``` - -Our inventory will now include `a hammer`, and when we print it with `<>`, we'll now see it: - -``` -OUTPUT: -a hammer -``` - -If you were to add another `a hammer`, it **will not** stack them or ignore the duplicate by default, instead, a new hammer is added. - -``` -<> -<> -``` -``` -OUTPUT: -a hammer -a hammer -a wrench -``` - -This may be counter to your expectations, so be wary. - -However, we can get around this using a variety of methods. Let's say that you want the hammers to stack, and show `2 hammers`. In this case, we can use an *inventory event* to catch the second hammer before it joins our inventory. - -```javascript -$(document).on(':invetory-update', function (ev) { - if (ev.context === 'pickup') { - if (ev.instance.has('a hammer') && ev.moved.includes('a hammer')) { - var arr = Inventory.removeDuplicates(ev.instance); - ev.instance.empty().pickUp(arr); - ev.instance.drop('a hammer'); - ev.instance.pickUp('2 hammers'); - } - } -}); -``` - -As you can see, this is a labor-intensive and difficult process. This inventory system is designed for key-type items, not stackable inventories. The more items you wish to allow to stack, the more complicated and messy this becomes. I *highly* recommend using a different system altogether if stackable items are important to your game. - -If you instead want the player to only be able to carry a single item of each name in the inventory at a time, i.e., the player can only have one hammer at a time, this is much simpler to achieve. - -``` -<> -<> -``` -``` -OUTPUT: -a hammer -a wrench -``` - -In the above example, if they player already has either a hammer or a wrench, then they won't get duplicates of these items. - -If you need to remove duplicates *later* or only when displaying the inventory, you may instead wish to use the `Inventory.removeDuplicates()` method. - -``` -<> -``` - -This creates an **array** of item names made from the inventory's item list that doesn't include any duplicates. It does not edit the inventory you pass to it, but you can have it do that. - -``` -<<= _items.join(', ')>> /% prints a list with duplicates removed %/ -<><> /% removes all duplicates from an inventory %/ -``` - -Generally, if you need uniqueness, it's best to handle that via `<>` macros rather than after the fact, but there are some reasons to do the latter. - ------ - -To remove items from an inventory, the `<>` macro will remove an item, and the `<>` macro will completely empty the inventory. - -``` -<> -``` - -Note that if the inventory has duplicates, `<>` will only remove one instance of each item, but it's possible to call it with several items in a row to remove multiples. - -``` -<> -``` - -If the item(s) requested for the drop isn't in the inventory, nothing at all happens, and no errors are reported. Do to this, you generally want to check the inventory before `<>`ing; for example, if the player needs to use a key and then lose it, a common construction will probably look more like this: - -``` -There's a door leading into the castle here. - -<>\ - <> - <> - <>\ -<>\ - The door's rusted lock won't budge.\ -<>\ - -[[Leave.|previous()]] -``` - -The above construction will let the player unlock the door if they have a key or if they've already been past the door (under the assumption the key is required for that). It's possible to get more granular than this, reporting different messages based on whether the door was already unlocked or not: - -``` -There's a door leading into the castle here. - -<>\ - The door is open a bit. - - [[Go into the castle.|inside]]\ -<>\ - You believe you've found the key. - - <> - <> - <>\ -<>\ - The door's rusted lock won't budge.\ -<>\ - -[[Leave.|previous()]] -``` - -Clearing the entire inventory is probably suitably rare. - -## Testing an inventory for items - -The `has()` and `hasAll()` methods are used to test the inventory for items. - -``` -<> - You have a tree branch! -<> -``` - -When checking for a single item, the `has()` method is recommended. When you want to check for a collection of items, you can use either `has()` or `hasAll()` depending on your needs; the former returns `true` if *any* of the requested items are in the inventory, while the latter only returns `true` if *all* of the requested items are found in the inventory. - -``` -<> - You can start a fire! -<> - -<> - You can take a picture! -<> -``` - -## Displaying an inventory - -Descr. - -## Multiple inventories - -Descr. \ No newline at end of file diff --git a/docs/simple-inventory.md b/docs/simple-inventory.md deleted file mode 100644 index c05c626..0000000 --- a/docs/simple-inventory.md +++ /dev/null @@ -1,802 +0,0 @@ -## The Simple Inventory System (v2.x) - -[Back to the main readme](./README.md). - -> [!NOTE] -> [Simple Inventory v3](https://inventory.twinelab.net/) is currently in beta! Once it stabilizes, this version of the Simple Inventory will be retired and the simple inventory will no longer be part of this collection. - -The simple inventory allows Twine authors to create and manipulate array-based inventories for 'key' style items (as opposed to consumables or equipment). This system provides a great deal of functionality, including sorting, displaying item lists (with drop / transfer links), and creating multiple inventories (for creating 'rooms' or other containers, or party members) and transfering items between them. All of the functionality here has both a JavaScript API and a TwineScript Macro-based API, meaning the features are easily available from within your passages and inside scripts. - -> [!DANGER] -> The simple inventory has undergone some pretty major changes since it first debuted. Version 1 was mostly a bit of syntactic sugar over an array system designed to help less-experienced authors utilize standard JavaScript arrays and methods in a scripting style they were more comfortable with (that is, macros). On rewriting this system, it seemed like a good idea to push things a little farther and create something that could be useful even to more experienced authros (hopefully, anyway). The changes make simple inventory a much more robust and feature-rich system, but unfortunately, **old code written for v1.x of simple inventory is not compatible with the new simple inventory system**. - -**THE CODE:** [Minified](https://github.com/ChapelR/custom-macros-for-sugarcube-2/blob/master/scripts/minified/simple-inventory.min.js). [Pretty](https://github.com/ChapelR/custom-macros-for-sugarcube-2/blob/master/scripts/simple-inventory.js). -**DEMO:** [Available](http://macros.twinelab.net/demo?macro=inventory). -**GUIDE:** [Available](./guides/simple-inventory-guide.md). - -### Contents - - * [The Options Object](#the-options-object) - * [the `tryGlobal` option](#option-tryglobal) - * [the `defaultStrings` option](#option-defaultstrings) - * [The Macros](#the-macros) - * [the `<>` macro](#macro-newinventory) - * [the `<>` macro](#macro-pickup) - * [the `<>` macro](#macro-drop) - * [the `<>` and `<>` macros](#macro-dropall-and-clear) - * [the `<>` macro](#macro-transfer) - * [the `<>` macro](#macro-sort) - * [the `<>` macro](#macro-inventory) - * [the `<>` macro](#macro-linkedinventory) - * [Functions and Methods](#functions-and-methods) - * [the `Inventory()` contructor](#the-inventory-constructor) - * [Static Methods](#static-methods) - * [Instance Methods](#instance-methods) - * [Events](#the-events) - * [Changelog](#changelog) - -### The Options Object - -The options object can be found near the top of the script (in the pretty version). It looks like this: - -```javascript -var options = { - tryGlobal : true, // send constructor to global scope - defaultStrings : { - empty : 'The inventory is empty...', - listDrop : 'Discard', - separator : '\n' - } -}; -``` - -It is recommended that you leave the `tryGlobal` option as `true` unless you know what you're doing. - -#### Option: `tryGlobal` - -The functions, methods, and variables used by these systems all exist on the special SugarCube `setup` object. For ease of access to authors, everything that might be of use to them is then sent to the global scope as `window.Inventory`. If you don't want to send this object to the global scope, you can change this option to `false`. - -> [!NOTE] -> Even if this option is set to `true`, the script will check to make sure `window.Inventory` is undefined before overwriting it. - -If the global `Inventory` object is unavailable, either because you changed this setting or because it was already in use, you can still access things: replace `Inventory...` with `setup.Inventory...` in your code, or create your own gobal reference. - -#### Option: `defaultStings` - -This set of options represents the default strings used for certain situations: - - * `empty`: when the inventory is empty, this text is displayed instead of a list of items. You can use valid TwineScript syntax in the string, i.e. `empty: "<>"` would be a valid value. - * `listDrop`: the inventory system includes a macro called `<>` for constructing a list of items with links that allow dropping and transfering items when clicked. These links' text *should* be set up in the macro, but you can set up default link text that will appear in case an invalid argument is passed; you can then pass an empty string (`''`) as a shortcut to display this as the link. - * `separator`: when using the `<>` macro or the `.show()` method to display a list of items, you can determine how you want the items to be serparated when using those macros by supplying a string. If no string is supplied, this default separator is used instead (the default value of `'\n'` represents a newline in JavaScript). - -### The Macros - -The following is a list of macros included in the simple inventory system. - -#### Macro: `<>` - -**Syntax**: `<>` - -This macro creates a new inventory. Creating a new inventory is much like initializing a variable, and the best place to use this macro is in your `StoryInit` special passage. You must provide the macro with a valid TwineScript variable, passed in quotes (similar to how you might pass it to a `<>` macro). The new inventory will be stored in the provided variable. You can optionally pass the inventory a list of items and the inventory will be initialized with these items inside it. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, in which to store the newly created inventory. - * **itemList**: (optional) A list of items to place in the inventory. This list should be one or more arrays of quoted strings, a space-separated list of quoted strings, or any combination of the two. If you use array literals directly in the macro's arguments, you need to wrap them in backticks (\`). See "Passing an expression as an argument" [in the SugarCube docs](http://www.motoslave.net/sugarcube/2/docs/#macros-arguments). - -**Usage**: -``` -/% create a new, empty inventory in the $inventory variable %/ -<> - -/% create an inventory in the $playerInventory variable and place two items in it %/ -<> - -/% create an inventory for the kitchen room and call it $kitchenInventory and place some items in it %/ -<> - -/% create a suit case called $suitCase always contains a key, but also includes some random items %/ -<> -<> -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro adds items to inventory indicated by the $variable. These items are added to the end of the inventory. If the keyword `unique` is included before the item list, items that are already in the inventory will not be added to it. **Caution**: if the `unique` keyword is placed after the first item in the item list, an item called `unique` will be added to the inventory. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - * **unique**: (optional) The keyword `unique`. If passed before the item list, will enforce uniqueness--that is, items already in the inventory will not be picked up. - * **itemList**: A list of items to place in the inventory. This list should be one or more arrays of quoted strings, a space-separated list of quoted strings, or any combination of the two. If you use array literals directly in the macro's arguments, you need to wrap them in backticks (\`). See "Passing an expression as an argument" [in the SugarCube docs](http://www.motoslave.net/sugarcube/2/docs/#macros-arguments). - -**Usage**: -``` -/% add an item to the inventory %/ -<> - -/% you may wish to check if the player already has the item: %/ -@@#link; -<> - <> - <>You already have a gun, you don't need another...<> - <> - <> - <>You take the gun and hide it in your coat.<> - <> -<> -@@ - -/% you can also add several items at once %/ -You received your inheritance! -<> -<> - -/% unique items: %/ -:: StoryInit -<> - -:: A Later Passage -<> -/% only shield is added %/ - -:: Some Other Passage -/% however, be warned: %/ -<> -/% - an item named 'unique' is added to the inventory, - and the other items are also added, regardless of whether - they were already in the inventory -%/ -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro removes items from the inventory indicated by the $variable. If one or more of the provided items can't be found in the inventory, nothing happens and no error is thrown, so some caution may be required in debugging certain situations. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - * **itemList**: A list of items to remove from the inventory. This list should be one or more arrays of quoted strings, a space-separated list of quoted strings, or any combination of the two. If you use array literals directly in the macro's arguments, you need to wrap them in backticks (\`). See "Passing an expression as an argument" [in the SugarCube docs](http://www.motoslave.net/sugarcube/2/docs/#macros-arguments). - -**Usage**: -``` -/% drop an item %/ -<> - -/% have a random item stolen %/ -<> -<> - -/% drop all weapons %/ -:: StoryInit -<> -<> - -:: Prison -The guards frisk you and take your weapons. -<> -/% drops any item from _weaponList, if present %/ -``` - -#### Macro: `<>` and `<>` - -**Syntax**: `<>` or `<>` - -The `<>` macro removes **all** items from the inventory indicated by the $variable. The `<>` macro is an alternative that does the same thing. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - -**Usage**: -``` -/% clears the inventory %/ -<> - -/% <> also works %/ -A fire destroyed the mansion's kitchen! -<> -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro moves items from one inventory to another. The first inventory argument is the giver, and the second is the receiver. It's essentially the same as pairing a `<>` and `<>`, but has a few benefits over doing it that way. For one, if you were to `<>` an item from one inventory and have another `<>` the same item, you run the risk of having the reveiving inventory getting an item that the first inventory never had, since `<>` does nothing if the item doesn't exist. Using `<>`, if an item isn't present in the first inventory, the second inventory will not receive said item. Like `<>` no error will be raised in this case. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - * **itemList**: A list of items to transfer between the inventories. This list should be one or more arrays of quoted strings, a space-separated list of quoted strings, or any combination of the two. If you use array literals directly in the macro's arguments, you need to wrap them in backticks (\`). See "Passing an expression as an argument" [in the SugarCube docs](http://www.motoslave.net/sugarcube/2/docs/#macros-arguments). - -**Usage**: -``` -/% containers %/ -<> - <> -<> - -/% transfer weapons, so the player can get them back %/ -:: StoryInit -<> -<> -<> - -:: Prison -The guards frisk you and take your weapons. -<> - -:: Release -You've been released from prison, and your weapons are returned to you. -<> -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro sorts the indicated inventory in alphanumeric order. - -> [!WARNING] -> There's no easy way to restore the default chronological ordering. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - -**Usage**: -``` -<> -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro displays a list of the items in the indicated inventory. This list can be separated by a provided string. If no serparator argument is provided, the default separator is used. - -**Arguments**: - - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - * **separator**: (optional) The string used to separate the list of items. If omitted, the [default string](#option-defaultstrings) is used. - -**Usage**: - -Assume the inventory `$playerInv` contains: `'wallet'`, `'keys'`, `'phone'`, `'pocket knife'`, and `'candy bar'`. - -Example: - -``` -<> /% or just <> if the default strings aren't changed %/ -``` - -Result: - -``` -wallet -keys -phone -pocket knife -candy bar -``` - -Example: - -``` -<> -``` - -Result: - -``` -wallet, keys, phone, pocket knife, candy bar -``` - -Example: - -``` -<> -<> -``` - -Result: - -``` -candy bar - keys - phone - pocket knife - wallet -``` - -#### Macro: `<>` - -**Syntax**: `<>` - -The `<>` macro creates a list of items from the indicated inventory, and pairs each item with a link. If only one inventory variable is provided, the links, when clicked, will cause the items to be dropped from their current inventory as though the `<>` macro had been used. If a second inventory variable is included, items will instead be move from the first inventory to the second, as though the `<>` macro had been called. The **actionName** argument should be used to contextualize this action for the player. - -**Arguments**: - - * **actionName**: The name the link should be given for each entry. Use an empty string to shortcut to the [default action](#option-defaultstrings). - * **variableName**: The name of a $variable, which must be quoted, and which is storing an inventory created by `<>` or the `Inventory()` constructor. - -**Usage**: -``` -/% containers %/ -You open the box. Want to take anything with you? -<> - -/% let the player drop items %/ -<> - -/% let the player place items %/ -You open the closet. Lots of space in here. -<> -``` - -### Functions and Methods - -The following are the functions and methods that are included in the simple inventory. Most of these allow access to the simple inventory's features in pure JavaScript, while some of these features are only available through this JavaScript API: even if you aren't planning on interacting with this system through JavaScript, you should still read the documentation for `Inventory.removeDuplicates()`, `.has()`, and `.hasAll()`, all of which are either only available through JavaScript, or contain features that are only available for your TwineScript expressions through JavaScript. - -> [!TIP] -> **About chaining**: Methods that don't return an explicit value will return the inventory they are called on (listed with the return value of 'this inventory' in the below documentation), meaning you can **chain many of the instance method calls**. For example, `.pickUp()` adds items to the inventory, but doesn't need to return anything in specific, so it returns the inventory object is was called on and allows chaining. On the other hand, `.show()` returns a string, so it can't be chained with other inventory methods. For example: - -``` --> The following is valid: -<> - --> The following is not valid and will raise an error -<> -``` - -#### The `Inventory()` Constructor - -**Return Value**: A new inventory instance. - -**Syntax**: `new Inventory([itemList])` - -The `Inventory()` constructor creates a new inventory just as the `<>` macro does. While some checks are in place to help forgetful authors, this function should **always** be called with the `new` operator, as failing to do so could leak the inventory to the global scope or create other issues. Further, the call should always be saved to a variable (a story `$variable`, a temporary `_variable`, or a JavaScript variable) or the call might pollute the global scope. - -**Arguments**: - - * **itemList**: (optional) A list of items to place in the inventory. This list should be one or more arrays of quoted strings, a comma-separated list of quoted strings, or any combination of the two. - -**Usage**: - -All of the following examples are equivalent to `<>`: - -``` -/% using in a <> macro (also works in <>) %/ -<> - -// in JavaScript or in <