0 votes
by (460 points)

Hi,

I use an inventory using javascript :

// Inventory
window.getInv = function () {
	return State.variables.inventory;
};

Macro.add([ "initInv", "emptyInv" ], {
	handler : function () {
		State.variables.inventory = [];
		
		State.variables.inventory.findByID = function(obj) {
			if (this.length === 0) {
				return false;
			}
			if (typeof obj !== "object" || !obj.hasOwnProperty("id")) {
				return false;
			}
			var idx = this.findIndex(function (item) {
				return item.id === obj.id;
			});
			return (idx !== -1);
		};
	}
});

Macro.add("addToInv", {
	handler : function () {
		if (this.args.length === 0) {
			return this.error("no inventory item specified");
		}
		var obj = this.args[0];
		if (typeof obj !== "object" || !obj.hasOwnProperty("id")) {
			return this.error("inventory item malformed");
		}
		var idx = State.variables.inventory.findIndex(function (item) {
			return item.id === obj.id;
		});
		if (idx === -1) {
			State.variables.inventory.push(obj);
		}
	}
});

Macro.add("removeFromInv", {
	handler : function () {
		if (this.args.length === 0) {
			return this.error("no inventory item specified");
		}
		var obj = this.args[0];
		if (typeof obj !== "object" || !obj.hasOwnProperty("id")) {
			return this.error("inventory item malformed");
		}
		var idx = State.variables.inventory.findIndex(function (item) {
			return item.id === obj.id;
		});
		if (idx !== -1) {
			State.variables.inventory.splice(idx , 1);
		}
	}
});

Macro.add("inv", {
	handler : function () {
		if (State.variables.inventory.length === 0) {
			new Wikifier(this.output, 'nothing');
		} else {
			new Wikifier(
				this.output,
				'[[' + State.variables.inventory.map(function (item) {
					return item.name;
				}).join(']]<br>[[') + ']]');
		}
	}
});

Macro.add('listInv', {
	handler : function () {
		var $list = $(document.createDocumentFragment());

		if (State.variables.inventory.length === 0) {
			$list.text('nothing');
		}
		else {
			State.variables.inventory.forEach(function (item) {
				$list
					.wiki('[[' + item.name + ']]')
					.append('\u00A0\u00D7' + item.count)
					.append('<br>');
			});
		}

		$list.appendTo(this.output);
	}
});
// End Inventory Macros

That's a code of the old forum. I know it creates link.

My question is : Could someone modify it to this way : I would like the link go to a variable passage named $Inventory_Items, with a set as "$inventory_items to "item name".

Exemple :

[[Postit|$Inventory_Items][$Inventory_Items to "Postit"]]

Thx.

1 Answer

0 votes
by (159k points)
selected by
 
Best answer

note: It would help anyone answering your question if you supplied an example of the usage of the set of custom macros, otherwise that person needs to determine for themselves the valid property definition of an inventory object. eg. That the object must have an ID, a NAME and a COUNT property.

So assuming the TwineScript is going to look something like the following:

<<set $apple to {id: "apple", name: "Apple", count: 2}>>
<<set $orange to {id: "orange", name: "Orange", count: 3}>>
<<set $pear to {id: "pear", name: "Pear", count: 1}>>

<<addToInv $apple>>
<<addToInv $orange>>
<<addToInv $pear>>

<<set $Inventory_Items to "Postit">>

<<listInv>>


Then replacing the listInv macro related Javascript code in your Story Javascript area with the following example should achieve what you want.

Macro.add('listInv', {
	handler : function () {

		/* Check that the required variable exists then retrieve it's value. */
		var variable = 'Inventory_Items';
		if (! state.variables.hasOwnProperty(variable)) {
			return this.error(variable + ' variable not set');
		}
		var target = state.variables[variable];

		var $list = $(document.createDocumentFragment());

		if (State.variables.inventory.length === 0) {
			$list.text('nothing');
		}
		else {
			State.variables.inventory.forEach(function (item) {
				$list
					.wiki('[[' + item.name +
							'|' + target + ']' +
							'[$' + variable + ' to "' + item.name + '"]]')
					.append('\u00A0\u00D7' + item.count)
					.append('<br>');
			});
		}

		$list.appendTo(this.output);
	}
});


WARNING: You are using the $Inventory_Items story variable to represent two different things at the same time: the name of the Target Passage of the link; and the name of the Selected Inventory Item. Using a variable in this way is generally not a good idea because it can lead to confusion about what it's value is currently representing, It would make more sense to use two different named variables instead, each named based on it's purpose.
eg. like $InventoryTargetPassage and $SelectedInventoryItem or something similar that has meaning to you.

by (460 points)
edited by

Hi,

Thanks for your answer, and sorry for being so minimalist in the explanation.

I just modify what you do a little bit (I quickly understand when I've go an exemple ^^), here is the new one, As the Inventory is in a passage names "Inventory", I decide to stay in this passage and cut it in two, and to make the variable  $Inventory_Items a variable only.

Got an optionnal question, is the macro Inv and listInv have the same function ?

Macro.add('listInv', {
	handler : function () {

		/* Check that the required variable exists then retrieve it's value. */
		var variable = 'Inventory_Items';
		if (! state.variables.hasOwnProperty(variable)) {
			return this.error(variable + ' variable not set');
		}

		var $list = $(document.createDocumentFragment());

		if (State.variables.inventory.length === 0) {
			$list.text('nothing');
		}
		else {
			State.variables.inventory.forEach(function (item) {
				$list
					.wiki('[[' + item.name +
							'|' + 'Inventory' + ']' +
							'[$' + variable + ' to "' + item.name + '"]]')
					.append('\u00A0\u00D7' + item.count)
					.append('<br>');
			});
		}

		$list.appendTo(this.output);
	}
});

 

Concerning your Warning :

Is the risk high about confusion ?

I use it a lot, but I take care of having names as far as different as I can to avoid that.

...