Jump to content
  • 0

increment index number


Question

Posted (edited)

Hello.
Keep getting error.
Not able to increment index number from in a table.

This not work, error during incrementing.
error: attempt to index ? (a nil value) with key 'value' (field '?')

a = gg.getListItems()
gg.loadResults(a)
total = gg.getResultsCount(a) / 2

loop = 1

while (loop <= total) do
  
  
  for i = 1, #x do
    x[i].value = x[loop].value
  end
  gg.setValues(x)
  
  
  for i = 1, #z do
    z[i].value = z[loop].value
  end
  gg.setValues(z)
  
  gg.sleep(500)

 loop = loop + 1
 
end


If i don't try incrementing the index number by 1, the loop keeps iterating over the same elements at the given index...index number 1.
Script should basically do this:

  for i = 1, #x do
    x[i].value = x[1].value
  end
  gg.setValues(x)
  
  
  for i = 1, #z do
    z[i].value = z[1].value
  end
  gg.setValues(z)

  for i = 1, #x do
    x[i].value = x[2].value
  end
  gg.setValues(x)
  
  
  for i = 1, #z do
    z[i].value = z[2].value
  end
  gg.setValues(z)

  for i = 1, #x do
    x[i].value = x[3].value
  end
  gg.setValues(x)
  
  
  for i = 1, #z do
    z[i].value = z[3].value
  end
  gg.setValues(z)

till it iterate over all the results. of both the tables x and z.
incrimination of index number must be based on the total amount of results from the result Count divided by two.

Edited by XxhentaixX

Recommended Posts

  • 0
Posted
1 hour ago, CmP said:

The issue is in the code that needs to be repeated. When the code is executed for the first time, "value" fields of all sub-tables of the table ("x", for example) are set to "x[1].value", so that when the code is repeated and should set all values to second value, "x[2].value" is already modified to the value of "x[1].value", that's why each time the code is repeated, it sets all values to first value.

To actually set all values of a table to value of different table element each time, make sure that there is a copy of values that doesn't get modified and in the code that gets repeated just use values from the copy to set "value" field of sub-tables. To make copy of values, construct a table in which indexes from original table (1, 2, 3, ...) are mapped to values of "value" field of corresponding sub-tables of the original table (x[1].value, x[2].value, x[3].value, ...), for example, like this: 

local xValues = {}
for i, v in ipairs(x) do
  xValues[i] = v.value
end

Then use values of constructed table in inner loop of the code that gets repeated (slightly modified version of the loop from @TisNquyen's post above): 

for loop = 1, #x do
  for i = 1, #x do
    x[i].value = xValues[loop]
    y[i].value = yValues[loop]
  end
  gg.setValues(x)
  gg.setValues(y)
  gg.sleep(500)
end

working great.
This is not what i thought i writhed and it was a bit hard to figure out with the print function as the values change each every sec.
So x[i].value stays is equal to the element 1 as long it is in the "for loop"  ? I thought it would grab all the values again at each loop and increment set equal to incremented index number.

1 hour ago, TheMech said:

Once you set all of the values in x to the first, wouldn't the second value become the first?

No, the behavior of values was not mentioned.
But the values change based on coordinates of an object. So the values will never be the same. It's also why i use the sleep function. well, i only sended the relevant part of the script. But issue seems to be fixed now. can continue now.

  • 0
Posted
1 hour ago, CmP said:

The issue is in the code that needs to be repeated. When the code is executed for the first time, "value" fields of all sub-tables of the table ("x", for example) are set to "x[1].value", so that when the code is repeated and should set all values to second value, "x[2].value" is already modified to the value of "x[1].value", that's why each time the code is repeated, it sets all values to first value.

To actually set all values of a table to value of different table element each time, make sure that there is a copy of values that doesn't get modified and in the code that gets repeated just use values from the copy to set "value" field of sub-tables. To make copy of values, construct a table in which indexes from original table (1, 2, 3, ...) are mapped to values of "value" field of corresponding sub-tables of the original table (x[1].value, x[2].value, x[3].value, ...), for example, like this: 

local xValues = {}
for i, v in ipairs(x) do
  xValues[i] = v.value
end

Then use values of constructed table in inner loop of the code that gets repeated (slightly modified version of the loop from @TisNquyen's post above): 

for loop = 1, #x do
  for i = 1, #x do
    x[i].value = xValues[loop]
    y[i].value = yValues[loop]
  end
  gg.setValues(x)
  gg.setValues(y)
  gg.sleep(500)
end

 ok buddy, this is my mistake =))

  • 0
Posted (edited)
28 minutes ago, XxhentaixX said:

So x[i].value stays is equal to the element 1 as long it is in the "for loop"  ?

No, that's because all values of the table are explicitly set to value of first element when the following code is executed: 

for i = 1, #x do
  x[i].value = x[1].value
end

If, for example, "x" has 3 elements, the loop is then equivalent to: 

x[1].value = x[1].value -- value of first element is set to itself
x[2].value = x[1].value -- value of second element is set to value of first element
x[3].value = x[1].value -- value of third element is set to value of first element

And then, when next loop is executed: 

for i = 1, #x do
  x[i].value = x[2].value
end

"x[2].value" no longer has it's original value, because new value (of "x[1].value") has been assigned to it during execution of previous loop.

This is why only first loop works as intended and all subsequent ones don't. And this is why copy of values needs to be created before the first loop (to have access to original values after table values have been overwritten).

Edited by CmP
  • 0
Posted (edited)
gg.searchNumber('', gg.TYPE_FLOAT)
gg.refineNumber('', gg.TYPE_FLOAT)
local count = gg.getResultsCount()
local results = gg.getResults(count)

local _x, _y = {}, {}
for i, v in ipairs(results) do
  _x[i] = {address = v.address + 0x44, flags = gg.TYPE_FLOAT}
  _y[i] = {address = v.address + 0x4C, flags = gg.TYPE_FLOAT}
end
_x, _y = gg.getValues(_x), gg.getValues(_y)

local x, y = {}, {}
for i, v in ipairs(results) do
  if _x[i].value ~= '0' then
    table.insert(x, x[i])
  end
  if _y[i].value ~= '0' then
   table.insert(y, y[i])
  end
end

if #x ~= #y then
  return print "the results from x and y may not be the same!"
end
local xValue, yValue = x, y

for loop = 1, #x do
  for i, v in ipairs(x) do
    x[i].value = xValue[loop].value
    y[i].value = yValue[loop].value
  end
  gg.setValues(x)
  gg.setValues(y)
  gg.sleep(500)
end

if i want to have the same result of y and x then i will add it under yValue and xValue like so

Edited by TisNquyen
  • 0
Posted
3 minutes ago, TisNquyen said:
gg.searchNumber('', gg.TYPE_FLOAT)
gg.refineNumber('', gg.TYPE_FLOAT)
local count = gg.getResultsCount()
local results = gg.getResults(count)

local _x, _y = {}, {}
for i, v in ipairs(results) do
  _x[i] = {address = v.address + 0x44, flags = gg.TYPE_FLOAT}
  _y[i] = {address = v.address + 0x4C, flags = gg.TYPE_FLOAT}
end
_x, _y = gg.getValues(_x), gg.getValues(_y)

local x, y = {}, {}
for i, v in ipairs(results) do
  if _x[i].value ~= '0' then
    table.insert(x, x[i])
  end
  if _y[i].value ~= '0' then
   table.insert(y, y[i])
  end
end

if #x ~= #y then
  return print "the results from x and y may not be the same!"
end
local xValue, yValue = x, y

for loop = 1, #x do
  for i, v in ipairs(x) do
    x[i].value = xValue[loop].value
    y[i].value = yValue[loop].value
  end
  gg.setValues(x)
  gg.setValues(y)
  gg.sleep(500)
end

 

This code is equivalent to your previous version.

You don't make a copy of tables with this line: 

local xValue, yValue = x, y

Instead you create new variables that refer to the same tables, so it doesn't make any difference.

Lua reference manual explains this pretty clearly: 

Quote

Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.

  • 0
Posted
25 minutes ago, CmP said:

This code is equivalent to your previous version.

You don't make a copy of tables with this line: 

local xValue, yValue = x, y

Instead you create new variables that refer to the same tables, so it doesn't make any difference.

Lua reference manual explains this pretty clearly: 

you are right, if i do so then the result in xValue and yValue is still changed on LUA 5.3, but when i tried on gg I don't know how it worked 

local x, y = {}, {}
local xValue, yValue = {}, {}
for i, v in ipairs(results) do
  if _x[i].value ~= '0' then
    x[#x+1] = _x[i]
    xValue[#x] = x[#x]--.value
  end
  if _y[i].value ~= '0' then
    y[#y+1] = _y[i]
    yValue[#y] = y[#y]--.value
  end
end

 If you want to be more precise then try this

  • 0
Posted

There is one other detail regarding the comparison to "0" (string).

Behavior of comparison operators for this case is described in the manual as follows: 

Quote

Equality (==) first compares the type of its operands. If the types are different, then the result is false. Otherwise, the values of the operands are compared. Strings are compared in the obvious way. Numbers are equal if they denote the same mathematical value.

Equality comparisons do not convert strings to numbers or vice versa. Thus, "0"==0 evaluates to false, and t[0] and t["0"] denote different entries in a table.

The operator ~= is exactly the negation of equality (==).

For our case it means that the following condition

_x[i].value ~= '0'

will always evaluate to "true", because "value" field has value of number type.

Correspondingly, correct comparison to check for value being not equal to zero is: 

_x[i].value ~= 0
  • 0
Posted
18 minutes ago, CmP said:

There is one other detail regarding the comparison to "0" (string).

Behavior of comparison operators for this case is described in the manual as follows: 

For our case it means that the following condition

_x[i].value ~= '0'

will always evaluate to "true", because "value" field has value of number type.

Correspondingly, correct comparison to check for value being not equal to zero is: 

_x[i].value ~= 0

 it's still my fault, because I have never used this way of checking value before

v.value = '0'

I usually use this to set the value so it's a bit misleading =))

  • 0
Posted
13 hours ago, CmP said:

 

for i = 1, #x do
  x[i].value = x[2].value
end

"x[2].value" no longer has it's original value, because new value (of "x[1].value") has been assigned to it during execution of previous loop.

This is why only first loop works as intended and all subsequent ones don't. And this is why copy of values needs to be created before the first loop (to have access to original values after table values have been overwritten).

But its odd. So this means that when all the values of the elements are setted equal to the value of the first element it keeps a record of that current value saved, even if the value in the game has changed.
So let's say the current value in first element is -200 float. All values are setted to -200.
The value in the game changes to -205 (before the loop happens), then would that not mean that the value in the element in the array has to change to -205 as well and for that on the next loop edit all the values to -205 since the first element became -205.
I actually see the point that it keeps iterating over the same element, but let's say even value wise it not entirely makes sense.

  • 0
Posted
2 hours ago, XxhentaixX said:

But its odd. So this means that when all the values of the elements are setted equal to the value of the first element it keeps a record of that current value saved, even if the value in the game has changed.

This understanding is based on fundamental misconception that GG automatically updates anything in tables that have been returned with "getResults", "getValues" or other GG API functions. GG not only doesn't do that, but also wouldn't be able to do that without significant performance impact (just imagine having to read values from process memory for all elements of all tables that have been returned by GG API functions every N milliseconds).

So changes in process memory "automatically" don't affect anything in script anyhow. To get updated data from process memory, corresponding GG API function ("getValues") needs to be called, but even it doesn't change anything in table that is passed to it as argument, instead it returns new table that has new values in "value" field of it's sub-tables.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.