I'm finally ready to start working on my roguelike's inventory system.
With equipment in games, usually each item has multiple purposes, aspects and attributes. I'm not really certain how to go about adding, removing and accessing them all in the player's inventory, or updating the various stats and whatnot when a piece is equipped or unequipped.
Here's one weapon in the game now:
<<set $WepName = "hatchet">>
<<set $Skill = $AxeMaceSkill>>
<<set $WeaponBon = 0>>
<<set $WepWoundMod = 1.5>>
<<set $Parry = Math.floor(($Skill * 0.5) + 3 + $CombatReflexes + $DB)>>
There will almost certainly need to be more variables before the game goes alpha.
I have a basic understanding of arrays. I use one to take three numeric variables, sort them, and then assign the highest value to another variable. Beyond that, I'm no expert.
Didn't want to reinvent the wheel. If someone has some advice or suggestions before I get too deep into this, I'm certainly open to them!
Keep in mind, though, I'm a total newbie. This is my first time ever working with Twine, CSS, or JavaScript and I don't even have a rudimentary understanding of the latter two!
Thanks!
Comments
L goes over using JavaScript arrays in this blog post http://www.glorioustrainwrecks.com/node/5034
For storing information about weapons, you might try JavaScript Objects.
A quick example:
<<set $axe = {}>>
<<set $axe.name = "Axe">>
<<set $axe.damageRange = [1,5]>>
Object: <<print $axe>> which you don't use
Name: <<print $axe.name>>
Damage: <<print $axe.damageRange>>
This would allow you to swap in and out weapons with a simple
<<set $weapon = $axe>>
I'm very glad I asked, now! I'll toy with those.
My friends and I are really enjoying the current version of it, so a CYOA roguelike is possible!
Oh, and I did read L's blog post. It's how I re-discovered arrays, actually.
Thanks again!
Just wanted to say thanks again! That really helped a lot! I can''t imagine if I had tried to set weapons (and later armor) up as a series of if statements! XD
This new perspective is like night and day.
Here is a broadsword in my game: To have the player equip the sword, all I do is <<set $Weapon = $Broadsword>>. (In the future, it will be <<set $Player.Weapon = $Broadsword>>.)
In the combat code, which is beyond voluminous, I had to change a few variables. This isn't actual code in my game, but just as an example, I had to change <<set $Damage = $Damage + $WeaponBon>> to <<set $Damage = $Damage + $Weapon.WeaponBon>>.
Instead of rolling against $Skill to hit, now the code rolls against $Weapon.Skill.
Here's another change that's going to happen but hasn't yet.
Take a look at this line again: That's setting the weapon's skill ($Broadsword.Skill) to the player's broadsword skill ($BroadswordSkill).
However, the player should be an object.
After I make the player an object called $Player, that line of code ill have to say, Pretty cool, eh?
I'd post my game now, but at this point, it will be easy to mistake it for something that's a lot closer to being finished than it really is. It's an entirely playable game with random rooms and monsters and complex combat and treasure and traps and all that. However, it's a pale, bleak shadow of what it will be when completed.
However, I'll be happy to post large portions of code, basically everything if it will help someone.
You could make that somewhat more succinct by using an object literal.
I'd be interested to see how you're going about generating the map/rooms, actually.
I'd really like to print Instead of If you're using a hashmap or something like that, that would be fine. Unless you don't have the functionality. Then I've got my project for tomorrow.
"Have you written a script," she asks . . . ::)
Just kidding, just kidding! ;D
But, no, I'm afraid I'm quite new at all this, "all this" being even the very most basic foundations of CSS and JavaScript.
I usually aways set the number of items when they are received (<<set Item.amount = item.amount + 1>>), so I don't foresee this being an issue for me personally. I do this even for unique items.
But if I may ask, how are you printing out the contents of your inventory? Right now I'm using: To create an array and when I pick up an item I use: If you're using: How are you displaying a list of items (inventory screen) without checking for every single variable? I suppose I could do both, but that seems sloppy. Like... do a <<if $inv.indexOf("Potion") gte 1>> to make sure that player has at least 1 and then do a <<$Potion.amount>> for the quantity?
EDIT: Fixed typos. Ooof, its late. I should get to bed.
zzzZZ
-_-
In my attempt to figure out what I will do when I get there, I started working on printing the inventory.
I ran into a roadblock when trying to put an object into an object inside an object. Or, at least I think that's what I'm trying to do . . . Prints "10."
Prints "10, 25."
Prints "Potion."
Prints "Potion."
Prints "5."
Prints "5."
bad expression: state.history[0].variables.player.inventory.push is not a function
So, I'm messing with that right now . . .
This is a known bug as of right now.
2) You need to write it as $player.inventory["push"], not $player.inventory.["push"]
1) Plain Objects don't have push() - only Arrays and other things do.
Try this: Also, don't push() an Array into another Array, unless you really want an Array inside an Array.
Perhaps that I don't understand the difference between an array and an object is keeping me from understanding what I'm doing wrong.
Here's the code again: What if $sword was an object? I guess first I should ask if that is an object or an array. As far as I know, it's an object.
Now that it's an object, it can't be somehow added to $player.purse or $player.inventory?
I noticed you used "{}" for purse and "[]" for inventory. Is "{}" for an object and "[]" an array? I mean, I see the syntax difference between ["Stuff", "Stuff", 1, 25, "Stuff"] and { stuff: 1, stuff: "yes"}. But, is there more to the difference? Both can hold numbers and strings, but an object can have multiple properties at once?
I guess that all goes back to the question, "Can an object not hold an object?"
JavaScript arrays are just a special type of object with a little extra syntactical sugar on the side. There are two parts to that:
[list type=decimal]
Has a numeric length property and non-negative integer properties.
Inherits the Array prototype.
The former allows you to iterate over the object like an array, and pass it to functions expecting to be able to iterate over it like an array. The latter gives the object access to all of the "array" methods from the Array prototype. Objects which meet both criteria are considered arrays. Object which only meet the former are called array-like objects. Objects only meeting the latter aren't terribly useful.
The properties on objects (and arrays) can reference anything a variable can: strings, numbers, objects, arrays, functions, etc.
When creating literals, {} creates an plain/generic object literal and [] creates an array literal.
Yes, an object can contain multiple properties. Yes, an object can contain/reference other objects via its properties. Your last example shows both of those actually.
The object referenced by $player, contains the properties purse, which references an object with its own properties (gold and silver), and inventory, which references an array with its own properties (length, 0, 1, 2, 3, and others inherited from the Array prototype).
You may find JavaScript @ Mozilla Developer Network informative.
I screwed up royally when I asked if an object could contain an object because, like you point out, the above code does just that. What I meant to askif I can get it out now that it's 3 a.m. againis can an object held in an object hold an object?
The question isn't as important as the code example; for two days now, I haven't been able to do this: At first, I thought it was because of the bug, then, I thought it was because I used ".["push"]" instead of "inventory["push"]."
Now what am I doing wrong? ;D
Thanks again!
Here are the (non-inherited) properties of $player.inventory at that point: Thus, you have to refer to the sword object (which by now is completely nameless) as $player.inventory[4].amount.
Of course, that's fairly unreadable, and indicates that you shouldn't be using an array at all if you need to refer to objects by their identity rather than their array location.
This topic seems to be drifting quite quickly away from Twine-specific minutiae.
Thanks again!
EDIT: The discussion in this thread is continued here: http://twinery.org/forum/index.php/topic,724.0.html