Twine version 2.0.8 SugarCube (v2.0.0-beta.4)
Novice user
RE: Inventory Macros by F2Andy:
http://strugglingwithtwine.blogspot.ca/2014/03/handling-inventory.html
Hi-
I want to make sidebar Inventory items droppable, so that if your running from the police or whatever you can simply click a blue ITEM link (in the case COFFEE) on the side bar to drop it. My first thought was that it should look something like this (when buying the item from a store.
So, I guess I'm trying to put one Click in another Click and need to wrap it, but I don't know if that is even possible.:
*I added the brackets so your head wouldn't explode reading it.
$10 Coffee <<if $Money gte 10>><<click "Buy">><<set $Coffee to "yes">><<goto "Store">><<addToInv "
[[[[<<click "Coffee">><<set $Coffee to "no">><<removeFromInv Coffee>><<goto "Store">><</click>>]]]]">><<set $Money to $Money -10>><</click>><</if>>
Here are the two lines apart:
<<if $Money gte 10>><<click "Buy">><<set $Coffee to "yes">><<goto "Store">><<addToInv "Coffee">><<set $Money to $Money -10>><</click>><</if>>
<<click "Coffee">><<set $Coffee to "no">><<removeFromInv Coffee>><<goto "Store">><</click>>
Not asking anyone to do my homework for me, but didn't want to waste hours for something that can't be done, or would be easier doing elsewhere- like the inventory javascript.
Any thoughts are welcome- thanks!
Comments
If you're putting this into the UI bar, I hope you're using the StoryCaption special passage?
You need to modify the inventory macros, not attempt to jam <<click>> macros into them, because that's never going to work.
Additionally, the <<click>> macro has a forwarding argument, so there's no need to use <<goto>> with what you were trying to do (which, again, won't work). Also, you probably don't want to be forwarding the player to the "Store" whenever they drop an item.
I'd suggest something like the following, which cleans up the macros a little and adds a new one <<listInv>> (see below the code for details): The <<listInv>> macro prints a list of the inventory items (one per line) with a drop link for each. Furthormore, each drop link will dynamically update the list generated by <<listInv>>.
I added <<listInv>> separately, rather than simply replacing <<inv>>, so you could still print a simple comma-separated list of the inventory items without the dropping links and dynamic update bits.
Usage example:
I had altered F2Andy's code to create a second 'home' inventory. I updated yours too. The Inventory Home Version I put in the side bar as well, but without the drop command. Instead it can only be dropped from the Home location- since you can't be at work and destroy your home PC. I redid the <<goto Home>> on the Home Version to 'refresh' the home list, while at home, as items are dropped.
I will post them tonight after I replace Andy's instructions.
Long term, I'll try to figure out how to move things from inventory to inventory, but I don't really need it right now and I've been messing with the Inventory and Clock for two days and I'm sick of looking at them.
I got a simple clock to work and was able to set it, but the more complex one that goes in the script passage I could never figure out how to set it. Considering I never looked at code before a week ago, I shouldn't be screwing with either of them; I can't get the theme to Gremlins out of my head as I break things and try to fix them.
Mad Thanks Mad -Thrown
Oops, this works better than the last post. Things move freely back and forth and you no longer own something without buying it the first time, and the links refresh on screen.
Once you buy Rum the first time, you can take / leave it as much as you want, but if you 'drop / trash' it, you are still able to get it from home. So, for now the Rum is never gone...
Also, I couldn't replicated this shortcut: macros.initInv = macros.emptyInv in the new style of doing things. Is it still possible? I didn't know what object these macros are added to. Is it just the old "macros" object, or something new?
Lastly, what does window.getInv = function () do? Is it needed?
So, if anyone wants to answer the questions about "window.getInv" and about the name of the parent object, that would be neat.
Oh, and it's neat code as well.
Would this lead to bloat and slowness? Is it something better to avoid in complex games?
Making macro aliases is still possible, yes. Macros added via the API exist within the Macro object itself, but the macro definitions are privately scoped, so you can't simply assign references around. The macros object is only for legacy macros.
You can make macro aliases in a couple of ways. You may do so at the time of initial macro creation, in which case you simply specify an array of names. For example: You may also create an alias after the creation of the original by supplying the name of the original as the definition. For example:
When called (i.e. getInv()), it returns a reference to the $inventory (i.e. State.variables.inventory) array. And no, it's not really necessary in SugarCube 2; the macros don't use it and if you need a reference in some other JavaScript, you can use State.variables.inventory (getInv() is just a bit shorter to type).
Here's a version which is a bit more idiomatic SugarCube 2 (using State.variables and contains). It includes the <<emptyInv>> alias and a working <<listInv>>.
You'd have to have a method to show items which had been dropped, obviously, but yes, it's totally doable. I'd probably suggest a generic object or a Map, where the keys are the names of the passages where things have been dropped and the values are arrays of said dropped items.
It should be neither bloating or slow if done as I suggested above, since the object would only hold key/value pairs for however many passages the player had dropped things in. Even if you put all in-game items in that way (i.e. the player would originally find items via this system as well), it probably wouldn't be an issue.
I modified these for more complex objects, but I came across an issue I'd like some help with. So, here's the current code:
And this works perfectly, but it only works since I explicitly included the id field. Originally, I was only passing obj, like is in the original code. But it it was failing to find the index in removeFromInv. The only way I was able to get "<<removeFromInv obj>>" was to explicity hand it the name (id) of the object ("<<removeFromInv $leatherArmor>>").
So... is there a reason for this? Also, should I give all my objects a unique name field to reference them by? Or... it's not exactly that. What I mean is, do I really have to embed the object name within the object itself in order to be able to properly call it within the macro? Or... am I just not doing something right? Actually, I don't know how to debug in javascript, so I really have no idea what the obj that's being passed actually looks like.
Anyway, this might be an issue that's likely to come up again and again, so any info in this would be helpful.
See the above. The existing <<listInv>> builds each entry as a string, so trying to concatenate an object into that was never going work. Your workaround works by storing the $variable name within id as a string.
Little bit of A, little bit of B. Yes, your inventory objects will need unique identifiers. If done correctly, no, they do not have to be names of $variables.
Try the following updated set which works with objects (and only objects). A couple of notes first:
Macros for an object-based key-item inventory:
As for the last macro, that's gonna have to wait until I move on to jquery study. But, even like this, I think I could incorporate some more stuff. Like (equip) to wield or wear the item. I can see how I'd do that. I also want to see about presenting the dropped items in the room again. That's pretty easy too.
What I'm not sure about right now is if my story would benefit from this unique-item approach or just having generic stuff where it doesn't necessarily matter what one gets deleted. My previous version was a bit like that. So, not much a key-item take on things. Right now, I could go either way, but I'll have to see how the story would fit into the more selective item gathering. It could work, depending.
Either way, I like seeing your coding. One thing I was considering was depicting wear and tear on weapons and stuff. The object approach would lend itself to that kind of tracking. Not everything would need to be tracked like this though, and I intend for quite a few items to be in-game. A lot of them generic "herb" type crafting things.
Thanks for the help, Exile. I appreciate it.
The only real cheat I did was to leave ".append("x" + item.count)" as is. So, you end up with x1 for single items. But, that doesn't look too bad either.
Here's what I used to test things with:
Thanks again, Exile. I doubt I could have done this without your expertise.
So, to clean that up, I figured out that it was best to have initial counts = 1 (not 0), and take out the obj.count++; line in addToInv macro.
So, only those changes. Here's the corrected code.
I mostly have it this way so I can have lots and lots of items. Or the illusion of that, without the actual object overload. Anyway, I'm still just playing with this stuff, but this is something I corrected, so I thought I'd present it here, just in case.
Basically I search all over the net to try to find some code that does something similar to what I need, cannibalize it, and play mad scientist to see how it works. I know enough to make a mess of things and spend 2 weeks trying to overthink a small problem. I present my problem and my solution and ask for people(Mad) to check my work. I'm sure I'll look back later at the way I did things later and think WTF, I used 100 lines of code when I could've done it a different way with 10.
I did tinker around with dropping things some more and got it to run smoother, but either to store at a set location (home), or to toss it if 'the man' was chasing you. That's all I really needed it for, so that's the solution I was solving for.
On a different note, my laptop croaked and I finally got around to ordering a new one, so I will begin to pester Mad anew!
I think I might start over, even though I have 20k worth of text in there. I tried to have just one location for multiple classes and times in the game and use a massive amount of IF statements to trigger per character / time. I should have done different character Hubs so there are 2 police station passages, 1 if your a cop and one for a crook. I didn't know when I started that the Grid on the story board expands- I thought I had very limited space.