#### Howdy, Stranger!

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

# A Question About Objects and Arrays/Lists

First of all, I may not be using the correct nomenclature in the subject title, so I apologize right now if not.

The creative and intelligent CoraBlue and I worked on this for quite some time one night, but I need further help. Since I don't know JavaScript, this is about the only place I can turn.

Let's say we have three objects:
`<<set \$player = { name: "Player", attack: 10, defense: 10, armor: 10, hp: 10, speed: 10,}>>`
`<<set \$goblin = { name: "Goblin", attack: 5, defense: 5, armor: 0, hp: 5, speed: 9,}>>`
`<<set \$orc = { name: "Orc", attack: 10, defense: 5, armor: 0, hp: 10, speed: 8,}>>`
Now, we also have a list:
`<<set \$sequence = []>>`
What I'd like to do is place all three object's speeds in the list, then sort them from greatest to least. This will create a turn sequence.

Here's what we do to get the player's, goblin's and orc's speeds into the list:
`<<set \$sequence.push(\$player.speed)>><<set \$sequence.push(\$goblin.speed)>><<set \$sequence.push(\$orc.speed)>>`
Then, we sort them from greatest to least.
`<<set \$sequence.sort(function(a,b){return b-a})>>`
If we print \$sequence, we see "10,9,8". That's correct.

However, all that does is provide a list of numbers sorted from greatest to least. There's no "attachment" that I know how to use from those numbers to the objects from which they are derived.

All that said, I don't even know where to begin stating my question. I think I want to show a passage based on whose turn it is in the sequence. So, for the player, they would get a bunch of combat options. For the goblin, it would attack the player. Same for the orc. After that, a loop would start the process again.

I imagine a loop needs to be ran and for each speed in \$sequence, a passage be displayed.

here's what I have figured right now:
`::loop<<if \$i lt \$sequence.length>><<print \$sequence[\$x]>><<set \$x = \$x+1>><<set \$i = \$i+1>><<loop>><<endif>>`
That works as I'd like. The loop correctly prints \$sequence[0], "10;" then \$sequence[1], "9;" then \$sequence[2], "8."

If instead of printing those numbers, I wonder how I could get it to display the correct passage (or even if that would be what I would want).

As far as I can tell, I need to somehow combine a passage variable with the speed, then sort by speed, then print the corresponding passage variable. I don't know if that can be done.

CoraBlue figured it out, but it's all in JavaScript and Greek to me, so I can't edit her work and I can't fix issues or change the way things operate when needed. So, I'm requesting help.

• Realistically, there's probably no way you're going to get away with not learning some javascript for this project!

So, it sounds like you what you really want is an array of the original objects, sorted by their speed; in other words, not just an array of the speed values. Here's some code to do that:

http://blog.favo.org/post/55605441602/javascript-sort-array-of-objects-by-key-property

If you added the name of the appropriate passage to each object as its "passage" property, you could just access that property of the object and <<display>> it.

By the way, I would make an Actor prototype ("class") and create each of my actors as an instance of that class. Here's a pretty good introduction to objects in javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
• Thanks!

Erik wrote:
If you added the name of the appropriate passage to each object as its "passage" property, you could just access that property of the object and <<display>> it.

That's at the heart of my question. I don't know how to do that. Of course, I can add a passage property, but I don't know how to display it, let alone display it in order.

[quote]By the way, I would make an Actor prototype ("class") and create each of my actors as an instance of that class. Here's a pretty good introduction to objects in javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

Yeah, I know about classes and instances, but it's just one more thing on top of a huge mountain of things that I need to learn. XD
• Given this:
`<<set \$player = { name: "Player", attack: 10, defense: 10, armor: 10, hp: 10, speed: 10, passage: "Player Attack"}>>`
You'd display the passage like this:
`<<display \$player.passage>>`
Or, if you're working with a sorted array of actor objects, e.g. \$sequence = [\$player, \$orc, \$goblin]:
`<<display \$sequence[\$i].passage>>`
• Erik wrote:
Or, if you're working with a sorted array of actor objects:
`<<display \$sequence[\$i].passage>>`

Hmmm . . . Well, now we're talking. Lemme chew on that.

Thanks again!
• Well, I hope I'm getting closer. I don't know JavaScript syntax well enough to get everything correct.
`::Twine Passage<<set \$sequence = [40,100,1,5,25,10]>><<sort>><<print \$sequence>>`
`macros['sort'] = { handler: function(place, macroName, params, parser) { var list = state.history[0].variables.sequence; list.sort(function(a,b){return a-b}); state.history[0].variables.sequence = list; }, };`
This works, but I'm still trying to figure out how to sort by object properties . . .
• `::Twine Passage<<Player>><<Goblin>><<Orc>><<set \$sequence = [\$player,\$goblin,\$orc]>><<sort>><<loop>>`
`::loop<<if \$i lt \$sequence.length>><<display \$sequence[\$x].passage>><<set \$x = \$x+1>><<set \$i = \$i+1>><<loop>><<endif>>`
`macros['sort'] = { handler: function(place, macroName, params, parser) { var list = state.history[0].variables.sequence; list.sort(function (b, a) { if (a.speed > b.speed) return 1; if (a.speed < b.speed) return -1; // a must be equal to b return 0; }); state.history[0].variables.sequence = list; },};`
I got the object sort function from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Okay. That seems to work . . .

All tests are go . . .
• `<<set \$player = { name: "Player", attack: 10, defense: 10, armor: 10, hp: 10, speed: 10, passage: "Player Attack"}>>`
Is it possible to place a true or false value inside that class? (if class is the right word here?) or its it only really numeric values that can be placed?
• I've always just used 1's and 0's or strings "true" and "false" so I don't know. However, you can set object properties to variables (e.g., speed: \$foo), and those variables can be true/false, I suppose.

By the way, this ended up not working perfectly. Not because there was anything wrong with the JS I wrote, but because only copies of the object are placed inside the list. It works as long as you don't go to another passage . . . The fix is vastly more complicated than I'm capable of understanding right now.

I gave up at working at this level of complexity for now.
• Okay thanks. Even on a basic level its handy to know and use.
• Dazakiwi38 wrote:
`<<set \$player = { name: "Player", attack: 10, defense: 10, armor: 10, hp: 10, speed: 10, passage: "Player Attack"}>>`
Is it possible to place a true or false value inside that class? (if class is the right word here?) or its it only really numeric values that can be placed?

This is just an update to my question above. I have discovered how do it after browsing some javascript pages namely this one https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean

So you put in the above example for Player Object;

Alive: (true),
• There's no need to use parenthesis with boolean literals.  This will work just fine:
`Alive: true,`
• More about ...... Javascript Arrays

Kerry

Dazakiwi38 wrote:

Okay thanks. Even on a basic level its handy to know and use.