The 3rd Age

Build anywhere mod (buildmod)

Build anywhere mod (buildmod)

Let's you build anywhere in skirmish

Button for The 3rd AgeButton for The Dwarf HoldsButton for The Elven AllianceButton for Helm's Deep Last HopeButton for GothmogtheOrcButton for BFME+Button for The Four AgesButton for HDR HeadquartersButton for Middle Earth CenterButton for Project Perfect Mod

Become an affiliate!

   

Quick Lists

Top Rated Popular New Updated Last Comments Users

Register and log in to move these advertisements down

Advanced LUA: Helper Functions

Tutorial for Battle for Middle-earth BFME

Avatar of Nertea

Nertea

Category: Code
Level: Expert
Created: Wednesday November 18, 2009 - 0:43
Updated: Wednesday November 18, 2009 - 1:56
Views: 13252
Summary: Learn about how to use lua helper functions in BFME1

Rating

Staff says

4.7

Members say

5.0

Average

4.7/5.0

7 votes

Page 1 2 3 4
This part of the tutorial deals with a function to randomize some subobjects.

Hopefully I got the message accross on the last page, because this is more of a demo page. To randomize subobjects, I wrote a more complex function. Understanding it will require some knowledge of programming and the lua language.

The function gives the user 3 parameters: a self object, a list of subobjects to be hidden, and a list of the probabilties for each object. The user can actually leave the probabilities blank, and the script will assume everything has an equal probability of appearing. It's clever that way.

              
Code

-- This function randomly (or not so randomly) unhides a set of subobjects
-- --------------------------------------------------
-- # Inputs: self: an instance of the object
-- #     subObjectTable: a table containing strings naming all the subobjects to be randomized
-- #         probTable:     a table containing probabilties from 0 to 1.0.
-- #                If shorter than subObjectTable, the script will assume all remaining objects have zero probability
-- #                Each probability corresponds to the subobject with the same index.
-- #                If the probabilities add to more than 1.0, the script will use equal probabilties
-- #                 Is not required, function will assume equal probability if left empty
function RandomizeSubobjects(self,subObjectTable,probTable)

    -- Error checking
    local redFlag = false
    if probTable then
        -- See if probabilities add to more than 1.0
            local sum = 0
            -- Loop through table, sum probabilites
            for i=1,getn(probTable) do
                sum = sum + probTable[i]
            end
            -- If the sum is greater than 0 or less than 1, set the red flag
            if (sum > 1.0) or (sum < 1.0) then
                redFlag = true
            end
        -- See if there are too few probabilities
            -- If there are, set the remainder to zero
            if getn(probTable) < getn(subObjectTable) then
                while getn(probTable) < getn(subObjectTable) do
                    probTable[getn(probTable)+1] = 0
                end
            end
    end

    -- If we don't have a probability table, or redFlag was true, use equal probabilities
    if (not probTable) or (redFlag) then
        -- Generate a random number
        local number = GetRandomNumber()
        -- Get the probability of getting each object
        local increment = 1/getn(subObjectTable)
        local curProb = increment
        
        -- For each subobject...
        local length = getn(subObjectTable)
        for i=1,length do
            if number <= curProb then
                -- If our random # is less than the target probability, unhide the object and
                -- break the loop
                ObjectHideSubObjectPermanently( self, subObjectTable[i], false )
                break
            end
            -- Increment the probability
            curProb = curProb + increment
        end
    else
        -- Generate a random number
        local number = GetRandomNumber()
        -- Our starting probability is the first item in the table
        local curProb = probTable[1]
        
        -- For each subobject...
        local length = getn(subObjectTable)
        for i=1,length do
            if number <= curProb then
                -- If our random # is less than the target probability, unhide the object and
                -- break the loop
                ObjectHideSubObjectPermanently( self, subObjectTable[i], false )
                break
            end
            -- Probability increases to the second probability
            curProb = curProb + probTable[i+1]
        end
        
    end
end


I can use this script in the Orc Warrior code from before to shorten it even further.

              
Code

-- Orc Fighter randomization
function OnMordorOrcACreated(self)

    local helmetList = {"HELM1","HELM2","HELM3","HELM4","HELM5","HELM6","HELM7"}
    local shieldList = {"SHIELD1","SHIELD2","SHIELD3","SHIELD4","SHIELD5","SHIELD6","SHIELD7","SHIELD8","SHIELD9"}
    local weaponList = {"1HW1","1HW2","1HW3","1HW4","1HW5","1HW6","1HW7","1HW8","1HW9","1HW10","1HW11","1HW12","1HW13"}

    HideAllSubObjects(self,shieldList)
    HideAllSubObjects(self,helmetList)
    HideAllSubObjects(self,weaponList)

    RandomizeSubobjects(self,helmetList)
    RandomizeSubobjects(self,shieldList)
    RandomizeSubobjects(self,weaponList)
end

This code calls the RandomizeSubobjects function three times with each of those lists. Look how short it is! This part does't use the probabilities, assuming they're all the same, but it could be modified to use them like this:
              
Code

-- Orc Fighter randomization
function OnMordorOrcACreated(self)

    local helmetList = {"HELM1","HELM2","HELM3","HELM4","HELM5","HELM6","HELM7"}
    local helmetProbs = {0.3, 0.2, 0.1, 0.1, 0.05, 0.05, 0.2}
    local shieldList = {"SHIELD1","SHIELD2","SHIELD3","SHIELD4","SHIELD5","SHIELD6","SHIELD7","SHIELD8","SHIELD9"}
    local shieldProbs = {0.1, 0.1, 0.2, 0.05, 0.05, 0.2, 0.1, 0.1, 0.1}
    local weaponList = {"1HW1","1HW2","1HW3","1HW4","1HW5","1HW6","1HW7","1HW8","1HW9","1HW10","1HW11","1HW12","1HW13"}
    local weaponProbs = {0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.4}

    HideAllSubObjects(self,shieldList)
    HideAllSubObjects(self,helmetList)
    HideAllSubObjects(self,weaponList)

    RandomizeSubobjects(self,helmetList,helmetProbs)
    RandomizeSubobjects(self,shieldList,shieldProbs)
    RandomizeSubobjects(self,weaponList,weaponProbs)
end


This allows you to save a lot of time and effort in basic randomization operations. If you have a helper function like this, you can quickly write many randomization scripts for many units, with stupid errors being less likely (less typos if there's less typing!)

The next page deals with those pesky lists up top...

Comments

Display order: Newest first

Nertea (Team Chamber Member) - Tuesday December 22, 2009 - 10:25

lua tables aren't really pure arrays because of their interesting key/record system. I'm not really a programmer, but my experience with actual programming languages has shown that lua tables don't behave the same way, so I guess it's ok for them to call them something else. Kinda like python's lists really.

they're defined like that because EA broke something somewhere - I couldn't get it to work using the normal way of declaring a table key/record.

Bart (Administrator) - Friday December 18, 2009 - 5:47

Nice tutorial. I wonder why LUA calls arrays tables though.
And why do you have to do this:
a = "foo"; list[a] = "bar"
instead of just:
list["foo"] = "bar"

Nertea (Team Chamber Member) - Saturday November 21, 2009 - 13:42

Glad it's a bit helpful. I do want to know if anybody uses this, and with what degree of success, partially for interest's sake and partially to see if it's worth writing up stuff about other lua script tricks that I've developed/am developing.

Rob38 (Team Chamber Member) - Thursday November 19, 2009 - 18:29

Interesting. I also use lots of random stuff for my models so this can be very helpful.

Sulherokhh (Team Chamber Member) - Wednesday November 18, 2009 - 6:39

Yippee! I love tuts like that, easily accessible and immediately useful.
Info #3 is a vital debugging tool. :)

Go to top

 

"One site to rule them all, one site to find them,
one site to host them all, and on the network bind them."

 
7:23:14