Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Accessing a Nested Object

December 04 (5 years ago)
SᵃᵛᵃǤᵉ
Sheet Author
API Scripter

I an trying to replicate a table that uses two variables to produce a third. I think I have the constant figured out but I am stuck.

	// ======= CONSTANT OCCUPANT HIT TABLE =======
	const occupantHitTable = [
		{o:1 [{10, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3}]},
		{o:2 [{12, 10, 9, 8, 7, 6, 5, 4, 3, 3, 3}]},
		{o:3 [{14, 12, 10, 9, 8, 7, 6, 5, 4, 3, 3}]},
		{o:6 [{16, 14, 12, 10, 9, 8, 7, 6, 5, 4, 3}]},
		{o:11 [{17, 16, 14, 12, 10, 9, 8, 7, 6, 5, 4}]},
		{o:21 [{17, 17, 16, 14, 12, 10, 9, 8, 7, 6, 5}]},
		{o:51 [{17, 17, 17, 16, 14, 12, 10, 9, 8, 7, 6}]},
		{o:101 [{17, 17, 17, 17, 16, 14, 12, 10, 9, 8, 7}]},
		{o:201 [{17, 17, 17, 17, 17, 16, 14, 12, 10, 9, 8}]}

		];

The actual table

Any help would be greatly appreciated.

December 04 (5 years ago)

Edited December 04 (5 years ago)
GiGs
Pro
Sheet Author
API Scripter

The first think to notice about that table is all the columns are identical, just shifted up or down 1 level for each size modifier.

There's also a repeating pattern to the number of occupants that makes it relatively simple to convert to a simple lookup/find.

Here's a function that will give you the value from the table. If you had 50 occupants, and a size modifier of 3, you'd call it like this

let modifier= occupantHit(50, 3);

The function:

const occupantHit = (occupants, size) => {
    // find the power of 10; 10-99 = 1, 100-999 = 2, etc.
    const poweroften = Math.max(0,Math.floor(Math.log10(occupants)));
         // divide occupants by poweroften to get in a rang of 1-9.
    const divided = Math.ceil(occupants/Math.pow(10,poweroften));
    // get row of table; size reduces row by its score
    const row = 10 - [1,2,3,6].reverse().findIndex(i => divided >= i) + poweroften * 3 - (size -1);
    
    //convert row into values
    const values = [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 17];
    // if row > value that gives 17, return 17; if 0 or less, return 3; otherwise get value from table.
    const result = row > 11 ? 17 : (row <= 0 ? 3 : values[row]);
    return result;
};


December 05 (5 years ago)
SᵃᵛᵃǤᵉ
Sheet Author
API Scripter

The occupant pattern isn't on a power of ten. "1, 2, 3-5, 6-10, 11-20, 21-50, 51-100, 101-200, 201-500" So I am not following your logic.


December 05 (5 years ago)

Edited December 05 (5 years ago)
GiGs
Pro
Sheet Author
API Scripter

Have you tested the function? Give it a try - it works.

There is a repeating pattern in those numbers: 

--1
23-56-10
11-2021-5051-100
101-200201-500501-1000

Notice if you divide the numbers on each row by 10 and round up, you get the row above it.

So, in the table, each power of ten is 3 rows down the table.

In this line

const row = 10 - [1,2,3,6].reverse().findIndex(i => divided >= i) + poweroften * 3 - (size -1);

the powerten *3 part uses a multiple of 3, because there are 3 columns per power of 10.

The [1,2,3,6].find part of the expression is a complicated-looking (but easier than a never-ending if/else) way to find out which column the number lands in, and the rest is used to normalise the number so it works with the following values array.

December 05 (5 years ago)
SᵃᵛᵃǤᵉ
Sheet Author
API Scripter

I was still trying to wrap my brain around it and then plug it into a full on sheetworker with attributes and all.

December 05 (5 years ago)
GiGs
Pro
Sheet Author
API Scripter

One thing I forgot to mention: the function doesnt check if the occupants and size parameters are valid numbers and above 0. i didnt know how you were using the function, so didnt know how to represent that. So you should ensure your inputs are valid.

December 05 (5 years ago)
GiGs
Pro
Sheet Author
API Scripter


SᵃᵛᵃǤᵉ said:

I was still trying to wrap my brain around it and then plug it into a full on sheetworker with attributes and all.

No problem, text is cruel. My response wasn't meant to be a rebuke, but encouragement to give it a go.

I didnt realise it was for a sheet worker. If you want help plugging it in, let me see what the sheet worker looks like.

Note that if occupants and size are from attributes on the sheet, you'll want to validate them - do the parseInt thing, and make sure that values are each 1 or higher.