LUA patches for levels in Sarven Desert Campaign

Cubic Minefield

```lua -- Walk through the minefield

– This function returns the number multiplied by the times
local mult = function(number, times)
local total = 0
while times > 0 do
total = total + number
times = times - 1
end
return total
end

– This function returns the number to the exponent power.
local power = function(number, exponent)
local total = 1
– Complete the function.

return total

end

– Dont change the follow code
– You can find coefficients for the equation on the tower
local tower = self:findFriends()[1]
local a = tower.a
local b = tower.b
local c = tower.c
local d = tower.d
local x = hero.pos.x

while true do
– To find the path use a cubic equation
local y = a * power(x, 3) + b * power(x, 2) + c * power(x, 1) + d * power(x, 0)
hero:moveXY(x, y)
x = x + 5
end

<hr>
1 Like

Sarven Savior

Introduction:

An array is a list of items.

-- An array of strings:
local friendNames = {'Joan', 'Ronan', 'Nikita', 'Augustus'}

Overview:

Arrays are ordered lists of data. In this level, you have an array storing the string names of your four friends.

In order to save your friends, you’ll need to tell each one of them to return home in turn. You can use the provided sample code to loop over an array.

-- friendNames is an array.
local friendNames = {'Joan', 'Ronan', 'Nikita', 'Augustus'}

--You can access specific elements of an array using a number surrounded by square brackets:
local name = friendNames[1]

-- Causes the hero to say: "Joan"
hero:say(name)

You can use an index variable instead of a number, to access an element of the array.

To loop over all the values in an array, use a while-loop to increment the index variable each loop!

On each pass through the loop, you’ll retrieve the friend name at that array index, then tell the friend to go home.

local friendNames = {'Joan', 'Ronan', 'Nikita', 'Augustus'}

-- Arrays start at index 1
local friendIndex = 1

-- #friendNames gives you the length of the friendNames array.
-- The length is equal to the number of items in the array (4, in this case)

while friendIndex <= #friendNames do
    local friendName = friendNames[friendIndex]
    hero:say(friendName .. ', go home!')
    friendIndex = friendIndex + 1
end
-- This while-loop will execute using friendIndex 1, then 2, 3, and 4
-- Note that in LUA the length of the array and the last element is 4!
1 Like

Lurkers

Overview:
Now that you’re familiar with arrays, you can use the method findEnemies() to get an array containing all the enemies your hero can see.

Notice that the sample code uses another while loop to make sure your hero keeps attacking the shaman while it’s health is greater than 0!

The logic for which enemies to attack has been provided for you, you need to put it within a while loop, where you loop over the enemies to find all the "shaman".

while enemyIndex <= #enemies do
    local enemy = enemies[enemyIndex]
    if enemy.type == 'shaman' then
        while enemy.health > 0 do
            hero:attack(enemy)
        end
    end
    enemyIndex = enemyIndex + 1
end

Important: make sure you increment the enemyIndex every time the loop runs, even if the enemy isn’t a shaman!

1 Like

Team Work

```lua -- Gems will disappear soon. You ll need help!

– findItems() returns an array of items.
local items = hero:findItems()

– Get the first gem from the array.
– Dont forget that the first index is 1.
local gem0 = items[1]

– Tell Bruno to get gem0
hero:say("Bruno " … gem0)

– You can reference the gem without a variable.
hero:say("Matilda " … items[1])

– Create a variable for the last gem, items[3]:

– Move to that gems position using moveXY()

<hr>

Introduction:

`hero:findItems()` returns an array containing all the items your hero can see.

```lua
local items = hero:findItems()
local first = items[1] # The first index is 1
local second = items[2]
local third = items[3]

When you assign an item to a variable, you can work with it as you did it with the findNearestItem() in previous levels.


Overview:

Methods like findItems, findEnemies and findFriends return an array filled with items, enemies, or friends).

Elements of an array are counted starting from 0, so the first element of the array has an index of zero.
To get an element of the array use the array[n] syntax, where n is an index of the required element.

local enemies = hero:findEnemies()
local firstEnemy = enemies[1]
local secondEnemy = enemies[2]

Be careful about the length of the array.
If you try to read an index that is greater than or equal to the array’s length you can get an error or undefined value,

You can assign elements of an array to a variable.

local items = hero:findItems()
local firstItem = items[1]
hero:moveXY(firstItem.pos.x, firstItem.pos.y)

You can also use array elements without assigning them to a variable:

local enemies = hero:findEnemies()
hero.attack(enemies[1])
1 Like

Coordinated Defense

-- Protect the peasants from the ogres.

while true do
    -- Get an array of enemies.
    local enemies = hero:findEnemies()
    -- If the array is not empty.
    if #enemies > 0 then
        -- Attack the first enemy from "enemies" array.
        
        -- Return to the start position.
        
    end
end

Introduction:

hero.findEnemies() returns an array of all the enemies you can see.

Attack the first enemy (index 0) in the array. Your allies will attack the others.

You need to check that the array of enemies isn’t empty.
One way to do this is to check that the length of the array is greater than 0:

local enemies = hero:findEnemies()
if #enemies > 0 then
    -- 'enemies' contains at least one element.
end

Overview:

The length of an array is the number of elements contained in the array. An empty array has a length of 0.

It is a good practice to check the length of the array if you need to read elements from it.

If you just need to read the first element, then it’s enough to check that the array isn’t empty.

local items = hero:findItems()
if #items then
    -- the length of "items" isn't 0.
    hero:say(items[1])
end

However if you are looking for another element like the third element, then you need to check the array length more precisely:

if #items >= 3 then
    -- "items" contains at least 3 elements.
    hero:say(items[3])
end
1 Like

Recruiting Queue

```lua -- Call peasants one after another.

– Neutral units are detected as enemies.
local neutrals = hero:findEnemies()
while true then
if #neutrals then
– Say the first unit in the neutrals array

else
    hero:say("Nobody here")
end

-- Reassign the neutrals variable using findEnemies()

end

<hr>
Overview:

Items can appear or be collected. Units might die or be summoned. 
As a result, arrays from methods like `findItems()`, `findEnemies()` and `findFriends()` can contain "old" data.
To avoid the problem, you should update those arrays every loop.

```lua
local enemies = hero:findEnemies()
while true do
    hero:attack(enemies[1])
    -- "enemies" can contain out of date data.
    -- Update it
    enemies = hero:findEnemies()
end
1 Like

Second Gem

```lua -- One gem is safe, the others are bombs. -- But you know the answer: always take the second.

while true do
local items = hero:findItems()
– If the length of items is greater or equal to 2:

    -- Move to the second item in items
    
-- Else:

    -- Move to the center mark.

end

<hr>

Overview:

You've learned how to use `findItems()` and access elements by indexes in previous levels.

In this level, the second item in the array of items is safe to collect.

Remember that the first item is at index `0`!
```lua
 -- LUA array elements are counted from 1

Zig Zag and Zoom

```lua -- Escape from Death Valley! -- The archers firing at you are not your allies! Dodge the arrows! -- Move by with a zigzag pattern using real modulo functions.

– This function returns a value from 0 to 15:
local mod15 = function(n)
while n >= 15 do
n = n - 15
end
return n
end

– This function should return a value from 0 to 9:
local mod9 = function(n)
– Use a while loop to modify the parameter before returning

return n

end

– Dont change the following code:
while true do
local time = hero:now()
local y
if time < 30 then
y = 10 + 3 * mod15(time)
else
y = 20 + 3 * mod9(time)
end
local x = 10 + time
hero:moveXY(x, y)
end

<hr>